Skip to content

Commit

Permalink
Attacher: new modes: Inertia CS, Inertia axes
Browse files Browse the repository at this point in the history
Modes added:
3D and plane attachment: Inertia CS
Line attachment: Inertia axes
This commit may serve a good example of how to add new attachment modes.
  • Loading branch information
DeepSOIC authored and wwmayer committed May 7, 2016
1 parent d12141d commit 9d19bf0
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 0 deletions.
85 changes: 85 additions & 0 deletions src/Mod/Part/App/Attacher.cpp
Expand Up @@ -52,6 +52,7 @@
# include <ShapeExtend_Explorer.hxx>
# include <GProp_GProps.hxx>
# include <GProp_PGProps.hxx>
# include <GProp_PrincipalProps.hxx>
# include <BRepGProp.hxx>
#endif
#include <BRepLProp_SLProps.hxx>
Expand Down Expand Up @@ -110,6 +111,13 @@ const char* AttachEngine::eMapModeStrings[]= {
"Vertex",
"ProximityPoint1",
"ProximityPoint2",

"AxisOfInertia1",
"AxisOfInertia2",
"AxisOfInertia3",

"InertialCS",

NULL};


Expand Down Expand Up @@ -775,6 +783,11 @@ AttachEngine3D::AttachEngine3D()
modeRefTypes[mmObjectXZ] = ss;
modeRefTypes[mmObjectYZ] = ss;

modeRefTypes[mmInertialCS].push_back(cat(rtAnything));
modeRefTypes[mmInertialCS].push_back(cat(rtAnything,rtAnything));
modeRefTypes[mmInertialCS].push_back(cat(rtAnything,rtAnything,rtAnything));
modeRefTypes[mmInertialCS].push_back(cat(rtAnything,rtAnything,rtAnything,rtAnything));

modeRefTypes[mmFlatFace].push_back(cat(rtFlatFace));

modeRefTypes[mmTangentPlane].push_back(cat(rtFace, rtVertex));
Expand Down Expand Up @@ -959,6 +972,37 @@ Base::Placement AttachEngine3D::calculateAttachedPlacement(Base::Placement origP
}

} break;
case mmInertialCS:{
GProp_GProps gpr = AttachEngine::getInertialPropsOfShape(shapes);
GProp_PrincipalProps pr = gpr.PrincipalProperties();
if (pr.HasSymmetryPoint())
throw Base::Exception("AttachEngine3D::calculateAttachedPlacement:InertialCS: inertia tensor is trivial, principal axes are undefined.");
if (pr.HasSymmetryAxis()){
Base::Console().Warning("AttachEngine3D::calculateAttachedPlacement:InertialCS: inertia tensor has axis of symmetry. Second and third axes of inertia are undefined.\n");
//find defined axis, and use it as Z axis
//situation: we have two moments that are almost equal, and one
//that is substantially different. The one that is different
//corresponds to a defined axis. We'll identify the different one by
//comparing differences.
Standard_Real I1, I2, I3;
pr.Moments(I1,I2,I3);
Standard_Real d12, d23, d31;
d12 = fabs(I1-I2);
d23 = fabs(I2-I3);
d31 = fabs(I3-I1);
if(d12 < d23 && d12 < d31){
SketchNormal = pr.ThirdAxisOfInertia();
} else if (d23 < d31 && d23 < d12){
SketchNormal = pr.FirstAxisOfInertia();
} else {
SketchNormal = pr.SecondAxisOfInertia();
}
} else {
SketchNormal = pr.FirstAxisOfInertia();
SketchXAxis = pr.SecondAxisOfInertia();
}
SketchBasePoint = gpr.CentreOfMass();
}break;
case mmFlatFace:{
if (shapes.size() < 1)
throw Base::Exception("AttachEngine3D::calculateAttachedPlacement: no subobjects specified (needed one planar face).");
Expand Down Expand Up @@ -1426,6 +1470,15 @@ AttachEngineLine::AttachEngineLine()

modeRefTypes[mm1Proximity].push_back(cat(rtAnything, rtAnything));

modeRefTypes[mm1AxisInertia1].push_back(cat(rtAnything));
modeRefTypes[mm1AxisInertia1].push_back(cat(rtAnything,rtAnything));
modeRefTypes[mm1AxisInertia1].push_back(cat(rtAnything,rtAnything,rtAnything));
modeRefTypes[mm1AxisInertia1].push_back(cat(rtAnything,rtAnything,rtAnything,rtAnything));
modeRefTypes[mm1AxisInertia2] = modeRefTypes[mm1AxisInertia1];
modeRefTypes[mm1AxisInertia3] = modeRefTypes[mm1AxisInertia1];



this->EnableAllSupportedModes();
}

Expand Down Expand Up @@ -1503,6 +1556,38 @@ Base::Placement AttachEngineLine::calculateAttachedPlacement(Base::Placement ori
case mmDeactivated:
//should have been filtered out already!
break;
case mm1AxisInertia1:
case mm1AxisInertia2:
case mm1AxisInertia3:{
GProp_GProps gpr = AttachEngine::getInertialPropsOfShape(shapes);
LineBasePoint = gpr.CentreOfMass();
GProp_PrincipalProps pr = gpr.PrincipalProperties();
if (pr.HasSymmetryPoint())
throw Base::Exception("AttachEngineLine::calculateAttachedPlacement:AxisOfInertia: inertia tensor is trivial, principal axes are undefined.");

//query moments, to use them to check if axis is defined
//See AttachEngine3D::calculateAttachedPlacement:case mmInertial for comment explaining these comparisons
Standard_Real I1, I2, I3;
pr.Moments(I1,I2,I3);
Standard_Real d12, d23, d31;
d12 = fabs(I1-I2);
d23 = fabs(I2-I3);
d31 = fabs(I3-I1);

if (mmode == mm1AxisInertia1){
LineDir = pr.FirstAxisOfInertia();
if (pr.HasSymmetryAxis() && !(d23 < d31 && d23 < d12))
throw Base::Exception("AttachEngineLine::calculateAttachedPlacement:AxisOfInertia: inertia tensor has axis of symmetry; first axis of inertia is undefined.");
} else if (mmode == mm1AxisInertia2) {
LineDir = pr.SecondAxisOfInertia();
if (pr.HasSymmetryAxis() && !(d31 < d12 && d31 < d23))
throw Base::Exception("AttachEngineLine::calculateAttachedPlacement:AxisOfInertia: inertia tensor has axis of symmetry; second axis of inertia is undefined.");
} else if (mmode == mm1AxisInertia3) {
LineDir = pr.ThirdAxisOfInertia();
if (pr.HasSymmetryAxis() && !(d12 < d23 && d12 < d31))
throw Base::Exception("AttachEngineLine::calculateAttachedPlacement:AxisOfInertia: inertia tensor has axis of symmetry; third axis of inertia is undefined.");
}
}break;
case mm1TwoPoints:{
std::vector<gp_Pnt> points;

Expand Down
7 changes: 7 additions & 0 deletions src/Mod/Part/App/Attacher.h
Expand Up @@ -92,6 +92,13 @@ enum eMapMode {
mm0Vertex,
mm0ProximityPoint1,
mm0ProximityPoint2,

mm1AxisInertia1,
mm1AxisInertia2,
mm1AxisInertia3,

mmInertialCS,

mmDummy_NumberOfModes//a value useful to check the validity of mode value
};//see also eMapModeStrings[] definition in .cpp

Expand Down
15 changes: 15 additions & 0 deletions src/Mod/Part/Gui/AttacherTexts.cpp
Expand Up @@ -92,6 +92,9 @@ TextSet getUIStrings(Base::Type attacherType, eMapMode mmode)
case mmFolding:
return TwoStrings(qApp->translate("Attacher3D", "Folding","Attachment3D mode caption"),
qApp->translate("Attacher3D", "Specialty mode for folding polyhedra. Select 4 edges in order: foldable edge, fold line, other fold line, other foldable edge. XY plane will be aligned to folding the first edge.","Attachment3D mode tooltip"));
case mmInertialCS:
return TwoStrings(qApp->translate("Attacher3D", "Inertial CS","Attachment3D mode caption"),
qApp->translate("Attacher3D", "Inertial coordinate system, constructed on principal axes of inertia and center of mass.","Attachment3D mode tooltip"));
default:
break;
}
Expand Down Expand Up @@ -146,6 +149,9 @@ TextSet getUIStrings(Base::Type attacherType, eMapMode mmode)
case mmFolding:
return TwoStrings(qApp->translate("Attacher2D", "Folding","AttachmentPlane mode caption"),
qApp->translate("Attacher2D", "Specialty mode for folding polyhedra. Select 4 edges in order: foldable edge, fold line, other fold line, other foldable edge. Plane will be aligned to folding the first edge.","AttachmentPlane mode tooltip"));
case mmInertialCS:
return TwoStrings(qApp->translate("Attacher2D", "Inertia 2-3","AttachmentPlane mode caption"),
qApp->translate("Attacher2D", "Plane constructed on second and third principal axes of inertia (passes through center of mass).","AttachmentPlane mode tooltip"));
default:
break;
}
Expand Down Expand Up @@ -203,6 +209,15 @@ TextSet getUIStrings(Base::Type attacherType, eMapMode mmode)
case mm1Proximity:
return TwoStrings(qApp->translate("Attacher1D", "Proximity line","AttachmentLine mode caption"),
qApp->translate("Attacher1D", "Line that spans the shortest distance between shapes.","AttachmentLine mode tooltip"));
case mm1AxisInertia1:
return TwoStrings(qApp->translate("Attacher1D", "1st principal axis","AttachmentLine mode caption"),
qApp->translate("Attacher1D", "Line follows first principal axis of inertia.","AttachmentLine mode tooltip"));
case mm1AxisInertia2:
return TwoStrings(qApp->translate("Attacher1D", "2nd principal axis","AttachmentLine mode caption"),
qApp->translate("Attacher1D", "Line follows second principal axis of inertia.","AttachmentLine mode tooltip"));
case mm1AxisInertia3:
return TwoStrings(qApp->translate("Attacher1D", "3rd principal axis","AttachmentLine mode caption"),
qApp->translate("Attacher1D", "Line follows third principal axis of inertia.","AttachmentLine mode tooltip"));
default:
break;
}
Expand Down

0 comments on commit 9d19bf0

Please sign in to comment.