Core: Datums: Fix axis placement and add migration script.
This commit is contained in:
@@ -207,9 +207,9 @@ const std::vector<LocalCoordinateSystem::SetupData>& LocalCoordinateSystem::getS
|
||||
{
|
||||
static const std::vector<SetupData> setupData = {
|
||||
// clang-format off
|
||||
{App::Line::getClassTypeId(), AxisRoles[0], tr("X-axis"), Base::Rotation()},
|
||||
{App::Line::getClassTypeId(), AxisRoles[1], tr("Y-axis"), Base::Rotation(Base::Vector3d(1, 1, 1), M_PI * 2 / 3)},
|
||||
{App::Line::getClassTypeId(), AxisRoles[2], tr("Z-axis"), Base::Rotation(Base::Vector3d(1,-1, 1), M_PI * 2 / 3)},
|
||||
{App::Line::getClassTypeId(), AxisRoles[0], tr("X-axis"), Base::Rotation(Base::Vector3d(1, 1, 1), M_PI * 2 / 3)},
|
||||
{App::Line::getClassTypeId(), AxisRoles[1], tr("Y-axis"), Base::Rotation(Base::Vector3d(-1, 1, 1), M_PI * 2 / 3)},
|
||||
{App::Line::getClassTypeId(), AxisRoles[2], tr("Z-axis"), Base::Rotation()},
|
||||
{App::Plane::getClassTypeId(), PlaneRoles[0], tr("XY-plane"), Base::Rotation()},
|
||||
{App::Plane::getClassTypeId(), PlaneRoles[1], tr("XZ-plane"), Base::Rotation(1.0, 0.0, 0.0, 1.0)},
|
||||
{App::Plane::getClassTypeId(), PlaneRoles[2], tr("YZ-plane"), Base::Rotation(Base::Vector3d(1, 1, 1), M_PI * 2 / 3)},
|
||||
@@ -277,6 +277,68 @@ void LocalCoordinateSystem::unsetupObject()
|
||||
}
|
||||
}
|
||||
|
||||
void LocalCoordinateSystem::onDocumentRestored()
|
||||
{
|
||||
GeoFeature::onDocumentRestored();
|
||||
|
||||
// In 0.22 origins did not have point.
|
||||
migrateOriginPoint();
|
||||
|
||||
// In 0.22 the axis placement were wrong. The X axis had identity placement instead of the Z.
|
||||
// This was fixed but we need to migrate old files.
|
||||
migrateXAxisPlacement();
|
||||
}
|
||||
|
||||
void LocalCoordinateSystem::migrateOriginPoint()
|
||||
{
|
||||
auto features = OriginFeatures.getValues();
|
||||
|
||||
auto featIt = std::find_if(features.begin(), features.end(),
|
||||
[](App::DocumentObject* obj) {
|
||||
return obj->isDerivedFrom(App::DatumElement::getClassTypeId()) &&
|
||||
strcmp(static_cast<App::DatumElement*>(obj)->Role.getValue(), PointRoles[0]) == 0;
|
||||
});
|
||||
if (featIt == features.end()) {
|
||||
// origin point not found let's add it
|
||||
auto data = getData(PointRoles[0]);
|
||||
auto* origin = createDatum(data);
|
||||
features.push_back(origin);
|
||||
OriginFeatures.setValues(features);
|
||||
}
|
||||
}
|
||||
|
||||
void LocalCoordinateSystem::migrateXAxisPlacement()
|
||||
{
|
||||
auto features = OriginFeatures.getValues();
|
||||
|
||||
bool migrated = false;
|
||||
|
||||
const auto& setupData = getSetupData();
|
||||
for (auto* obj : features) {
|
||||
auto* feature = dynamic_cast <App::DatumElement*> (obj);
|
||||
if (!feature) { continue; }
|
||||
for (auto data : setupData) {
|
||||
// ensure the rotation is correct for the role
|
||||
if (std::strcmp(feature->Role.getValue(), data.role) == 0) {
|
||||
if (!feature->Placement.getValue().getRotation().isSame(data.rot)) {
|
||||
feature->Placement.setValue(Base::Placement(Base::Vector3d(), data.rot));
|
||||
migrated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool warnedUser = false;
|
||||
if (!warnedUser && migrated) {
|
||||
Base::Console().Warning("This file was created with an older version of FreeCAD."
|
||||
"It had some origin's X axis with incorrect placement, which is being fixed now.\n"
|
||||
"But if you save the file here and open this file back in an "
|
||||
"older version of FreeCAD, you will find the origin objects axis looking incorrect."
|
||||
"And if your file is using the origin axis as references it will likely be broken.\n");
|
||||
warnedUser = true;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
LocalCoordinateSystem::LCSExtension::LCSExtension(LocalCoordinateSystem* obj)
|
||||
|
||||
@@ -213,6 +213,7 @@ protected:
|
||||
void setupObject() override;
|
||||
/// Removes all planes and axis if they are still linked to the document
|
||||
void unsetupObject() override;
|
||||
void onDocumentRestored() override;
|
||||
|
||||
private:
|
||||
struct SetupData;
|
||||
@@ -245,6 +246,9 @@ private:
|
||||
|
||||
DatumElement* createDatum(SetupData& data);
|
||||
SetupData getData(const char* role);
|
||||
|
||||
void migrateOriginPoint();
|
||||
void migrateXAxisPlacement();
|
||||
};
|
||||
|
||||
} // namespace App
|
||||
|
||||
@@ -83,12 +83,12 @@ void ViewProviderLine::attach(App::DocumentObject *obj) {
|
||||
|
||||
SbVec3f verts[2];
|
||||
if (noRole) {
|
||||
verts[0] = SbVec3f(2 * size, 0, 0);
|
||||
verts[0] = SbVec3f(0, 0, 2 * size);
|
||||
verts[1] = SbVec3f(0, 0, 0);
|
||||
}
|
||||
else {
|
||||
verts[0] = SbVec3f(size, 0, 0);
|
||||
verts[1] = SbVec3f(0.2 * size, 0, 0);
|
||||
verts[0] = SbVec3f(0, 0, size);
|
||||
verts[1] = SbVec3f(0, 0, 0.2 * size);
|
||||
}
|
||||
|
||||
// indexes used to create the edges
|
||||
@@ -107,7 +107,7 @@ void ViewProviderLine::attach(App::DocumentObject *obj) {
|
||||
sep->addChild ( pLines );
|
||||
|
||||
auto textTranslation = new SoTranslation ();
|
||||
textTranslation->translation.setValue ( SbVec3f ( size * 1.1, 0, 0 ) );
|
||||
textTranslation->translation.setValue(SbVec3f(0, 0, size * 1.1));
|
||||
sep->addChild ( textTranslation );
|
||||
|
||||
auto ps = new SoPickStyle();
|
||||
|
||||
@@ -1018,7 +1018,7 @@ static TopoShape _getTopoShape(const App::DocumentObject* obj,
|
||||
if (linked->isDerivedFrom(App::Line::getClassTypeId())) {
|
||||
static TopoDS_Shape _shape;
|
||||
if (_shape.IsNull()) {
|
||||
BRepBuilderAPI_MakeEdge builder(gp_Lin(gp_Pnt(0, 0, 0), gp_Dir(1, 0, 0)));
|
||||
BRepBuilderAPI_MakeEdge builder(gp_Lin(gp_Pnt(0, 0, 0), gp_Dir(0, 0, 1)));
|
||||
_shape = builder.Shape();
|
||||
_shape.Infinite(Standard_True);
|
||||
}
|
||||
|
||||
@@ -1357,9 +1357,10 @@ void ProfileBased::getAxis(const App::DocumentObject * pcReferenceAxis, const st
|
||||
}
|
||||
|
||||
if (pcReferenceAxis->isDerivedFrom<App::Line>()) {
|
||||
const App::Line* line = static_cast<const App::Line*>(pcReferenceAxis);
|
||||
base = Base::Vector3d(0, 0, 0);
|
||||
line->Placement.getValue().multVec(Base::Vector3d(1, 0, 0), dir);
|
||||
auto* line = static_cast<const App::Line*>(pcReferenceAxis);
|
||||
Base::Placement plc = line->Placement.getValue();
|
||||
base = plc.getPosition();
|
||||
plc.getRotation().multVec(Base::Vector3d(0, 0, 1), dir);
|
||||
|
||||
verifyAxisFunc(checkAxis, sketchplane, gp_Dir(dir.x, dir.y, dir.z));
|
||||
return;
|
||||
|
||||
@@ -338,17 +338,17 @@ class DocumentBasicCases(unittest.TestCase):
|
||||
|
||||
res = obj.getSubObject("X_Axis", retType=2)
|
||||
self.assertEqual(
|
||||
res[1].multVec(FreeCAD.Vector(1, 0, 0)).getAngle(FreeCAD.Vector(1, 0, 0)), 0.0
|
||||
res[1].multVec(FreeCAD.Vector(0, 0, 1)).getAngle(FreeCAD.Vector(1, 0, 0)), 0.0
|
||||
)
|
||||
|
||||
res = obj.getSubObject("Y_Axis", retType=2)
|
||||
self.assertEqual(
|
||||
res[1].multVec(FreeCAD.Vector(1, 0, 0)).getAngle(FreeCAD.Vector(0, 1, 0)), 0.0
|
||||
res[1].multVec(FreeCAD.Vector(0, 0, 1)).getAngle(FreeCAD.Vector(0, 1, 0)), 0.0
|
||||
)
|
||||
|
||||
res = obj.getSubObject("Z_Axis", retType=2)
|
||||
self.assertEqual(
|
||||
res[1].multVec(FreeCAD.Vector(1, 0, 0)).getAngle(FreeCAD.Vector(0, 0, 1)), 0.0
|
||||
res[1].multVec(FreeCAD.Vector(0, 0, 1)).getAngle(FreeCAD.Vector(0, 0, 1)), 0.0
|
||||
)
|
||||
|
||||
res = obj.getSubObject("XY_Plane", retType=2)
|
||||
|
||||
Reference in New Issue
Block a user