diff --git a/src/App/Datums.cpp b/src/App/Datums.cpp index 75a6b06e2b..c58c34b72f 100644 --- a/src/App/Datums.cpp +++ b/src/App/Datums.cpp @@ -207,9 +207,9 @@ const std::vector& LocalCoordinateSystem::getS { static const std::vector 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(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 (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) diff --git a/src/App/Datums.h b/src/App/Datums.h index 8e3d567ea1..002790e78b 100644 --- a/src/App/Datums.h +++ b/src/App/Datums.h @@ -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 diff --git a/src/Gui/ViewProviderLine.cpp b/src/Gui/ViewProviderLine.cpp index edf31b38cc..3cf3fdb85b 100644 --- a/src/Gui/ViewProviderLine.cpp +++ b/src/Gui/ViewProviderLine.cpp @@ -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(); diff --git a/src/Mod/Part/App/PartFeature.cpp b/src/Mod/Part/App/PartFeature.cpp index 48997300d4..ee3ab6948d 100644 --- a/src/Mod/Part/App/PartFeature.cpp +++ b/src/Mod/Part/App/PartFeature.cpp @@ -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); } diff --git a/src/Mod/PartDesign/App/FeatureSketchBased.cpp b/src/Mod/PartDesign/App/FeatureSketchBased.cpp index e8a467eff9..92f22da99a 100644 --- a/src/Mod/PartDesign/App/FeatureSketchBased.cpp +++ b/src/Mod/PartDesign/App/FeatureSketchBased.cpp @@ -1357,9 +1357,10 @@ void ProfileBased::getAxis(const App::DocumentObject * pcReferenceAxis, const st } if (pcReferenceAxis->isDerivedFrom()) { - const App::Line* line = static_cast(pcReferenceAxis); - base = Base::Vector3d(0, 0, 0); - line->Placement.getValue().multVec(Base::Vector3d(1, 0, 0), dir); + auto* line = static_cast(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; diff --git a/src/Mod/Test/Document.py b/src/Mod/Test/Document.py index 18ba7b1976..e59ab99e78 100644 --- a/src/Mod/Test/Document.py +++ b/src/Mod/Test/Document.py @@ -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)