Core: Datums: Fix axis placement and add migration script.

This commit is contained in:
PaddleStroke
2024-11-26 09:27:40 +01:00
parent d835cde3a5
commit 655ae579ed
6 changed files with 81 additions and 14 deletions

View File

@@ -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)

View File

@@ -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

View File

@@ -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();

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -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)