From: azv Date: Wed, 25 Mar 2015 06:10:47 +0000 (+0300) Subject: Supporting all types of objects (planes, lines, and points) as attributes of the... X-Git-Tag: V_1.1.0~85^2~5^2^2 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=9aad36a6b453e73b05356af4662a66a32cb71f1e;p=modules%2Fshaper.git Supporting all types of objects (planes, lines, and points) as attributes of the Placement feature --- diff --git a/src/FeaturesPlugin/FeaturesPlugin_Placement.cpp b/src/FeaturesPlugin/FeaturesPlugin_Placement.cpp index fd59eb386..f97b3248d 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Placement.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Placement.cpp @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -25,8 +26,8 @@ FeaturesPlugin_Placement::FeaturesPlugin_Placement() void FeaturesPlugin_Placement::initAttributes() { - data()->addAttribute(FeaturesPlugin_Placement::BASE_FACE_ID(), ModelAPI_AttributeSelection::type()); - data()->addAttribute(FeaturesPlugin_Placement::ATTRACT_FACE_ID(), ModelAPI_AttributeSelection::type()); + data()->addAttribute(FeaturesPlugin_Placement::BASE_OBJECT_ID(), ModelAPI_AttributeSelection::type()); + data()->addAttribute(FeaturesPlugin_Placement::ATTRACT_OBJECT_ID(), ModelAPI_AttributeSelection::type()); data()->addAttribute(FeaturesPlugin_Placement::REVERSE_ID(), ModelAPI_AttributeBoolean::type()); data()->addAttribute(FeaturesPlugin_Placement::CENTERING_ID(), ModelAPI_AttributeBoolean::type()); } @@ -34,41 +35,41 @@ void FeaturesPlugin_Placement::initAttributes() void FeaturesPlugin_Placement::execute() { // Verify the base face - std::shared_ptr aFaceRef = std::dynamic_pointer_cast< - ModelAPI_AttributeSelection>(data()->attribute(FeaturesPlugin_Placement::BASE_FACE_ID())); - if (!aFaceRef) + std::shared_ptr anObjRef = std::dynamic_pointer_cast< + ModelAPI_AttributeSelection>(data()->attribute(FeaturesPlugin_Placement::BASE_OBJECT_ID())); + if (!anObjRef) return; - std::shared_ptr aBaseFace = - std::dynamic_pointer_cast(aFaceRef->value()); - if (!aBaseFace) + std::shared_ptr aBaseShape = + std::dynamic_pointer_cast(anObjRef->value()); + if (!aBaseShape) return; - std::shared_ptr aBaseFaceContext; - ResultPtr aContextRes = aFaceRef->context(); + std::shared_ptr aBaseObject; + ResultPtr aContextRes = anObjRef->context(); if (aContextRes) { if (aContextRes->groupName() == ModelAPI_ResultBody::group()) - aBaseFaceContext = std::dynamic_pointer_cast(aContextRes)->shape(); + aBaseObject = std::dynamic_pointer_cast(aContextRes)->shape(); else if (aContextRes->groupName() == ModelAPI_ResultConstruction::group()) - aBaseFaceContext = std::dynamic_pointer_cast(aContextRes)->shape(); + aBaseObject = std::dynamic_pointer_cast(aContextRes)->shape(); } - if (!aBaseFaceContext) { + if (!aBaseObject) { static const std::string aContextError = "The selection context is bad"; setError(aContextError); return; } // Verify the attractive face - aFaceRef = std::dynamic_pointer_cast( - data()->attribute(FeaturesPlugin_Placement::ATTRACT_FACE_ID())); + anObjRef = std::dynamic_pointer_cast( + data()->attribute(FeaturesPlugin_Placement::ATTRACT_OBJECT_ID())); - std::shared_ptr aSlaveObjectFace = - std::dynamic_pointer_cast(aFaceRef->value()); - if (!aSlaveObjectFace) + std::shared_ptr aSlaveShape = + std::dynamic_pointer_cast(anObjRef->value()); + if (!aSlaveShape) return; std::shared_ptr aSlaveObject; - aContextRes = aFaceRef->context(); + aContextRes = anObjRef->context(); if (aContextRes) { if (aContextRes->groupName() == ModelAPI_ResultBody::group()) aSlaveObject = std::dynamic_pointer_cast(aContextRes)->shape(); @@ -81,13 +82,25 @@ void FeaturesPlugin_Placement::execute() return; } - // Verify faces planarity - std::shared_ptr aBaseFace1(new GeomAPI_Face(aBaseFace)); - std::shared_ptr aSlaveFace1(new GeomAPI_Face(aSlaveObjectFace)); - if (!aBaseFace1->isPlanar() || !aSlaveFace1->isPlanar()) { - static const std::string aPlanarityError = "One of selected face is not planar"; - setError(aPlanarityError); - return; + // Verify planarity of faces and linearity of edges + std::shared_ptr aShapes[2] = {aBaseShape, aSlaveShape}; + for (int i = 0; i < 2; i++) { + if (aShapes[i]->isFace()) { + std::shared_ptr aFace(new GeomAPI_Face(aShapes[i])); + if (!aFace->isPlanar()) { + static const std::string aPlanarityError = "One of selected faces is not planar"; + setError(aPlanarityError); + return; + } + } + else if (aShapes[i]->isEdge()) { + std::shared_ptr anEdge(new GeomAPI_Edge(aShapes[i])); + if (!anEdge->isLine()) { + static const std::string aLinearityError = "One of selected endges is not linear"; + setError(aLinearityError); + return; + } + } } // Flags of the Placement @@ -99,7 +112,7 @@ void FeaturesPlugin_Placement::execute() bool isCentering = aBoolAttr->value(); std::shared_ptr aResultBody = document()->createBody(data()); - GeomAlgoAPI_Placement aFeature(aSlaveObject, aBaseFaceContext, aSlaveFace1, aBaseFace1, isReverse, isCentering); + GeomAlgoAPI_Placement aFeature(aSlaveObject, aBaseObject, aSlaveShape, aBaseShape, isReverse, isCentering); if(!aFeature.isDone()) { static const std::string aFeatureError = "Placement algorithm failed"; setError(aFeatureError); diff --git a/src/FeaturesPlugin/FeaturesPlugin_Placement.h b/src/FeaturesPlugin/FeaturesPlugin_Placement.h index bf74f1364..8039f37e2 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Placement.h +++ b/src/FeaturesPlugin/FeaturesPlugin_Placement.h @@ -18,9 +18,9 @@ class GeomAPI_Shape; * \ingroup Plugins * \brief Feature for applying of placement operation: relative movement of Solid. * - * Locates the selected attractable_face of the solid in the middle of the selected - * placement_base face. Faces must be planar. Orientation of the placed solid is - * depended on the underlied planes of both faces. + * Locates the selected placement_attractable_object (face, edge, vertex) of the solid into + * the selected placement_base_object. Faces must be planar, edges must be linear. + * Orientation of the placed solid depends on the underlied planes of both faces. */ class FeaturesPlugin_Placement : public ModelAPI_Feature { @@ -31,17 +31,17 @@ class FeaturesPlugin_Placement : public ModelAPI_Feature static const std::string MY_PLACEMENT_ID("Placement"); return MY_PLACEMENT_ID; } - /// attribute name of referenced face - inline static const std::string& BASE_FACE_ID() + /// attribute name of referenced object + inline static const std::string& BASE_OBJECT_ID() { - static const std::string MY_BASE_FACE_ID("placement_base_face"); - return MY_BASE_FACE_ID; + static const std::string MY_BASE_OBJECT_ID("placement_base_object"); + return MY_BASE_OBJECT_ID; } /// attribute name of attractable face - inline static const std::string& ATTRACT_FACE_ID() + inline static const std::string& ATTRACT_OBJECT_ID() { - static const std::string MY_ATTRACT_FACE_ID("placement_attractable_face"); - return MY_ATTRACT_FACE_ID; + static const std::string MY_ATTRACT_OBJECT_ID("placement_attractable_object"); + return MY_ATTRACT_OBJECT_ID; } /// attribute name of flag of reverse direction inline static const std::string& REVERSE_ID() diff --git a/src/FeaturesPlugin/placement_widget.xml b/src/FeaturesPlugin/placement_widget.xml index 4a8832004..109d0d62c 100644 --- a/src/FeaturesPlugin/placement_widget.xml +++ b/src/FeaturesPlugin/placement_widget.xml @@ -1,17 +1,17 @@ - - diff --git a/src/GeomAPI/GeomAPI_Edge.cpp b/src/GeomAPI/GeomAPI_Edge.cpp index 4b758eb90..f9572daa7 100644 --- a/src/GeomAPI/GeomAPI_Edge.cpp +++ b/src/GeomAPI/GeomAPI_Edge.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -107,6 +108,26 @@ std::shared_ptr GeomAPI_Edge::circle() return std::shared_ptr(); // not circle } +std::shared_ptr GeomAPI_Edge::line() +{ + const TopoDS_Shape& aShape = const_cast(this)->impl(); + double aFirst, aLast; + Handle(Geom_Curve) aCurve = BRep_Tool::Curve((const TopoDS_Edge&)aShape, aFirst, aLast); + if (aCurve) { + Handle(Geom_Line) aLine = Handle(Geom_Line)::DownCast(aCurve); + if (aLine) { + gp_Pnt aStartPnt = aLine->Value(aFirst); + std::shared_ptr aStart( + new GeomAPI_Pnt(aStartPnt.X(), aStartPnt.Y(), aStartPnt.Z())); + gp_Pnt aEndPnt = aLine->Value(aLast); + std::shared_ptr aEnd( + new GeomAPI_Pnt(aEndPnt.X(), aEndPnt.Y(), aEndPnt.Z())); + return std::shared_ptr(new GeomAPI_Lin(aStart, aEnd)); + } + } + return std::shared_ptr(); // not circle +} + bool GeomAPI_Edge::isEqual(const std::shared_ptr theEdge) const { diff --git a/src/GeomAPI/GeomAPI_Edge.h b/src/GeomAPI/GeomAPI_Edge.h index 1c4802ecc..1ecbde0fc 100644 --- a/src/GeomAPI/GeomAPI_Edge.h +++ b/src/GeomAPI/GeomAPI_Edge.h @@ -11,6 +11,7 @@ class GeomAPI_Pnt; class GeomAPI_Circ; +class GeomAPI_Lin; /**\class GeomAPI_Edge * \ingroup DataModel @@ -41,9 +42,12 @@ public: /// Returns the Last vertex coordinates of the edge std::shared_ptr lastPoint(); - /// Returns a circle if edge is based on the cirsle curve + /// Returns a circle if edge is based on the circle curve std::shared_ptr circle(); + /// Returns a line if edge is based on the linear curve + std::shared_ptr line(); + /// Returns true if the current edge is geometrically equal to the given edge bool isEqual(const std::shared_ptr theEdge) const; }; diff --git a/src/GeomAPI/GeomAPI_Lin.cpp b/src/GeomAPI/GeomAPI_Lin.cpp index 27bd3e0e2..8b64190ba 100644 --- a/src/GeomAPI/GeomAPI_Lin.cpp +++ b/src/GeomAPI/GeomAPI_Lin.cpp @@ -6,6 +6,7 @@ #include #include +#include #include #include @@ -42,6 +43,18 @@ GeomAPI_Lin::GeomAPI_Lin(const std::shared_ptr& theStart, { } +std::shared_ptr GeomAPI_Lin::location() +{ + gp_Pnt aLoc = impl().Location(); + return std::shared_ptr(new GeomAPI_Pnt(aLoc.X(), aLoc.Y(), aLoc.Z())); +} + +std::shared_ptr GeomAPI_Lin::direction() +{ + const gp_Dir& aDir = impl().Direction(); + return std::shared_ptr(new GeomAPI_Dir(aDir.X(), aDir.Y(), aDir.Z())); +} + double GeomAPI_Lin::distance(const std::shared_ptr& thePoint) const { return MY_LIN->Distance(thePoint->impl()); diff --git a/src/GeomAPI/GeomAPI_Lin.h b/src/GeomAPI/GeomAPI_Lin.h index feefca238..cb7a73847 100644 --- a/src/GeomAPI/GeomAPI_Lin.h +++ b/src/GeomAPI/GeomAPI_Lin.h @@ -10,6 +10,7 @@ #include #include +class GeomAPI_Dir; class GeomAPI_Pnt; /**\class GeomAPI_Lin @@ -27,6 +28,12 @@ class GEOMAPI_EXPORT GeomAPI_Lin : public GeomAPI_Interface GeomAPI_Lin(const std::shared_ptr& theStart, const std::shared_ptr& theEnd); + /// Returns point on the line (first point) + std::shared_ptr location(); + + /// Returns a line direction + std::shared_ptr direction(); + /// Distance between two points double distance(const std::shared_ptr& thePoint) const; /// Intersection of two lines diff --git a/src/GeomAPI/GeomAPI_Lin2d.cpp b/src/GeomAPI/GeomAPI_Lin2d.cpp index 0a65590fa..3c784eefd 100644 --- a/src/GeomAPI/GeomAPI_Lin2d.cpp +++ b/src/GeomAPI/GeomAPI_Lin2d.cpp @@ -6,6 +6,7 @@ #include #include +#include #include #include @@ -36,6 +37,18 @@ GeomAPI_Lin2d::GeomAPI_Lin2d(const std::shared_ptr& theStart, { } +std::shared_ptr GeomAPI_Lin2d::location() +{ + gp_Pnt2d aLoc = impl().Location(); + return std::shared_ptr(new GeomAPI_Pnt2d(aLoc.X(), aLoc.Y())); +} + +std::shared_ptr GeomAPI_Lin2d::direction() +{ + const gp_Dir2d& aDir = impl().Direction(); + return std::shared_ptr(new GeomAPI_Dir2d(aDir.X(), aDir.Y())); +} + double GeomAPI_Lin2d::distance(const std::shared_ptr& theOther) const { return MY_LIN2D->Distance(theOther->impl()); diff --git a/src/GeomAPI/GeomAPI_Lin2d.h b/src/GeomAPI/GeomAPI_Lin2d.h index 5f6a02244..abb04bba8 100644 --- a/src/GeomAPI/GeomAPI_Lin2d.h +++ b/src/GeomAPI/GeomAPI_Lin2d.h @@ -10,6 +10,7 @@ #include #include +class GeomAPI_Dir2d; class GeomAPI_Pnt2d; /**\class GeomAPI_Lin2d @@ -27,6 +28,12 @@ class GEOMAPI_EXPORT GeomAPI_Lin2d : public GeomAPI_Interface GeomAPI_Lin2d(const std::shared_ptr& theStart, const std::shared_ptr& theEnd); + /// Returns point on the line (first point) + std::shared_ptr location(); + + /// Returns a line direction + std::shared_ptr direction(); + /// Distance between two points double distance(const std::shared_ptr& theOther) const; /// Intersection of two lines diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Placement.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Placement.cpp index e5714a22e..d2ab51bd5 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Placement.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Placement.cpp @@ -7,8 +7,12 @@ #include #include +#include +#include #include #include +#include +#include #include #include @@ -22,63 +26,157 @@ #define DEB_PLACEMENT 1 GeomAlgoAPI_Placement::GeomAlgoAPI_Placement( + std::shared_ptr theSourceSolid, + std::shared_ptr theDestSolid, std::shared_ptr theSourceShape, std::shared_ptr theDestShape, - std::shared_ptr theSourcePlane, - std::shared_ptr theDestPlane, bool theIsReverse, bool theIsCentering) : myDone(false), myShape(new GeomAPI_Shape()) { - build(theSourceShape, theDestShape, theSourcePlane, theDestPlane, theIsReverse, theIsCentering); + build(theSourceSolid, theDestSolid, theSourceShape, theDestShape, theIsReverse, theIsCentering); } void GeomAlgoAPI_Placement::build( + const std::shared_ptr& theSourceSolid, + const std::shared_ptr& theDestSolid, const std::shared_ptr& theSourceShape, const std::shared_ptr& theDestShape, - const std::shared_ptr& theSourcePlane, - const std::shared_ptr& theDestPlane, bool theIsReverse, bool theIsCentering) { - std::shared_ptr aSourcePlane = theSourcePlane->getPlane(); - std::shared_ptr aDestPlane = theDestPlane->getPlane(); - std::shared_ptr aSourceDir = aSourcePlane->direction(); - std::shared_ptr aSourceLoc = aSourcePlane->location(); - std::shared_ptr aDestDir = aDestPlane->direction(); - std::shared_ptr aDestLoc = aDestPlane->location(); + // Filling the parameters of the objects + static const int aNbObjects = 2; + gp_Pnt aSrcDstPoints[aNbObjects]; // points on the selected objects (0 - source, 1 - destination) + gp_Vec aSrcDstNormals[aNbObjects]; // normal vectors, if planar faces are selected + gp_Vec aSrcDstDirections[aNbObjects]; // directions of linear edges + bool hasNormal[aNbObjects]; + bool hasDirection[aNbObjects]; + std::shared_ptr aShapes[aNbObjects] = {theSourceShape, theDestShape}; + + for (int i = 0; i < aNbObjects; i++) { + if (aShapes[i]->isFace()) { + std::shared_ptr aFace(new GeomAPI_Face(aShapes[i])); + std::shared_ptr aPlane = aFace->getPlane(); + std::shared_ptr aDir = aPlane->direction(); + std::shared_ptr aLoc = aPlane->location(); + aSrcDstPoints[i].SetCoord(aLoc->x(), aLoc->y(), aLoc->z()); + aSrcDstNormals[i].SetCoord(aDir->x(), aDir->y(), aDir->z()); + } else if (aShapes[i]->isEdge()) { + std::shared_ptr anEdge(new GeomAPI_Edge(aShapes[i])); + std::shared_ptr aLine = anEdge->line(); + std::shared_ptr aDir = aLine->direction(); + std::shared_ptr aFirstPnt = anEdge->firstPoint(); + std::shared_ptr aLastPnt = anEdge->lastPoint(); + std::shared_ptr aLoc = aFirstPnt->xyz()->added(aLastPnt->xyz())->multiplied(0.5); + aSrcDstPoints[i].SetCoord(aLoc->x(), aLoc->y(), aLoc->z()); + aSrcDstDirections[i].SetCoord(aDir->x(), aDir->y(), aDir->z()); + } else if (aShapes[i]->isVertex()) { + std::shared_ptr aVertex(new GeomAPI_Vertex(aShapes[i])); + std::shared_ptr aPnt = aVertex->point(); + aSrcDstPoints[i].SetCoord(aPnt->x(), aPnt->y(), aPnt->z()); + } else // something goes wrong + return; + hasNormal[i] = aSrcDstNormals[i].SquareMagnitude() >= Precision::SquareConfusion(); + hasDirection[i] = aSrcDstDirections[i].SquareMagnitude() >= Precision::SquareConfusion(); + } + + // Calculate directions, which comply the normal, for vertices and edges + if (!hasNormal[0] || !hasNormal[1]) { + if (hasNormal[0] || hasNormal[1]) { // plane with line or vertex + if (hasDirection[0] || hasDirection[1]) { // plane - line + int anInd = hasDirection[0] ? 0 : 1; + gp_Vec aVec = aSrcDstNormals[1 - anInd].Crossed(aSrcDstDirections[anInd]); + if (aVec.SquareMagnitude() < Precision::SquareConfusion()) { // normal and direction are collinear + aVec = aSrcDstNormals[1 - anInd].Crossed( + gp_Vec(aSrcDstPoints[1 - anInd], aSrcDstPoints[anInd])); + if (aVec.SquareMagnitude() < Precision::SquareConfusion()) { // normal and points direction are collinear + if (Abs(aSrcDstNormals[1 - anInd].Y()) >= Precision::Confusion() || + Abs(aSrcDstNormals[1 - anInd].Z()) >= Precision::Confusion()) + aVec = gp::DX(); + else + aVec = gp::DY(); + } + } + aSrcDstNormals[anInd] = aSrcDstDirections[anInd].Crossed(aVec).Normalized(); + } else { // plane - point + int anInd = hasNormal[0] ? 1 : 0; + aSrcDstNormals[anInd] = aSrcDstNormals[1 - anInd]; + } + } else { + if (hasDirection[0] && hasDirection[1]) { // line - line + gp_Vec aVec = aSrcDstDirections[0].Crossed(aSrcDstDirections[1]); + if (aVec.SquareMagnitude() < Precision::SquareConfusion()) { // lines are parallel + aVec = aSrcDstDirections[0].Crossed(gp_Vec(aSrcDstPoints[0], aSrcDstPoints[1])); + if (aVec.SquareMagnitude() < Precision::SquareConfusion()) { // lines are equal + if (Abs(aSrcDstDirections[0].Y()) >= Precision::Confusion() || + Abs(aSrcDstDirections[0].Z()) >= Precision::Confusion()) + aVec = gp::DX(); + else + aVec = gp::DY(); + } + } + aSrcDstNormals[0] = aSrcDstDirections[0].Crossed(aVec); + aSrcDstNormals[0].Normalize(); + aSrcDstNormals[1] = aSrcDstDirections[1].Crossed(aVec).Reversed(); + aSrcDstNormals[1].Normalize(); + } else if (!hasDirection[0] && !hasDirection[1]) { // point - point + aSrcDstNormals[0] = gp_Vec(aSrcDstPoints[0], aSrcDstPoints[1]); + aSrcDstNormals[0].Normalize(); + aSrcDstNormals[1] = -aSrcDstNormals[0]; + } else { // line - point + int anInd = hasDirection[0] ? 0 : 1; + gp_Vec aVec(aSrcDstPoints[anInd], aSrcDstPoints[1 - anInd]); + aVec.Cross(aSrcDstDirections[anInd]); + if (aVec.SquareMagnitude() < Precision::SquareConfusion()) { // point is on line + if (Abs(aSrcDstDirections[1 - anInd].Y()) >= Precision::Confusion() || + Abs(aSrcDstDirections[1 - anInd].Z()) >= Precision::Confusion()) + aVec = gp::DX(); + else + aVec = gp::DY(); + } + aSrcDstNormals[anInd] = aSrcDstDirections[anInd].Crossed(aVec).Normalized(); + aSrcDstNormals[1 - anInd] = aSrcDstNormals[anInd]; + } + } + } // Initial shapes - const TopoDS_Shape& aSourceShape = theSourceShape->impl(); - const TopoDS_Shape& aDestShape = theDestShape->impl(); + const TopoDS_Shape& aSourceShape = theSourceSolid->impl(); + const TopoDS_Shape& aDestShape = theDestSolid->impl(); // Calculate transformation gp_Trsf aTrsf; - gp_Vec aSrcDir(aSourceDir->x(), aSourceDir->y(), aSourceDir->z()); - gp_Vec aDstDir(aDestDir->x(), aDestDir->y(), aDestDir->z()); + gp_Vec aSrcDir = aSrcDstNormals[0]; + gp_Vec aDstDir = aSrcDstNormals[1]; // Check the material of the solids to be on the correct side BRepClass3d_SolidClassifier aClassifier; - aClassifier.Load(aSourceShape); static const double aTransStep = 10. * Precision::Confusion(); - gp_Pnt aPoint(aSourceLoc->x(), aSourceLoc->y(), aSourceLoc->z()); - aPoint.Translate(aSrcDir * aTransStep); - aClassifier.Perform(aPoint, Precision::Confusion()); - if ((aClassifier.State() == TopAbs_OUT && !theIsReverse) || - (aClassifier.State() == TopAbs_IN && theIsReverse)) + if (hasNormal[0]) { + aClassifier.Load(aSourceShape); + gp_Pnt aPoint = aSrcDstPoints[0]; + aPoint.Translate(aSrcDir * aTransStep); + aClassifier.Perform(aPoint, Precision::Confusion()); + if ((aClassifier.State() == TopAbs_OUT && !theIsReverse) || + (aClassifier.State() == TopAbs_IN && theIsReverse)) + aSrcDir.Reverse(); + } else if (theIsReverse) aSrcDir.Reverse(); - aClassifier.Load(aDestShape); - aPoint.SetCoord(aDestLoc->x(), aDestLoc->y(), aDestLoc->z()); - aPoint.Translate(aDstDir * aTransStep); - aClassifier.Perform(aPoint, Precision::Confusion()); - if (aClassifier.State() == TopAbs_IN) - aDstDir.Reverse(); + if (hasNormal[1]) { + aClassifier.Load(aDestShape); + gp_Pnt aPoint = aSrcDstPoints[1]; + aPoint.Translate(aDstDir * aTransStep); + aClassifier.Perform(aPoint, Precision::Confusion()); + if (aClassifier.State() == TopAbs_IN) + aDstDir.Reverse(); + } // Calculate rotation gp_Quaternion aRot(aSrcDir, aDstDir); aTrsf.SetRotation(aRot); // Calculate translation - gp_Vec aSrcLoc(aSourceLoc->x(), aSourceLoc->y(), aSourceLoc->z()); - gp_Vec aDstLoc(aDestLoc->x(), aDestLoc->y(), aDestLoc->z()); + gp_Vec aSrcLoc(aSrcDstPoints[0].XYZ()); + gp_Vec aDstLoc(aSrcDstPoints[1].XYZ()); if (!theIsCentering) aDstLoc = aSrcLoc + gp_Vec(aDstDir) * (aDstLoc-aSrcLoc).Dot(aDstDir); aSrcLoc.Transform(aTrsf); diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Placement.h b/src/GeomAlgoAPI/GeomAlgoAPI_Placement.h index 703f609c1..1e1e88e49 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Placement.h +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Placement.h @@ -17,24 +17,24 @@ /**\class GeomAlgoAPI_Placement * \ingroup DataAlgo - * \brief Creates the copied object which face is placed on the given plane + * \brief Creates the copied object which sub-element is placed on the given element */ class GeomAlgoAPI_Placement : public GeomAPI_Interface { public: /** \brief Creates an object which is obtained from current object by transformation calculated - * as a movement of the source plane to be coincident with the destination plane - * \param[in] theSourceShape shape to be moved - * \param[in] theDestShape invariabt shape - * \param[in] theSourcePlane plane on the shape to be made coincident with destination plane - * \param[in] theDestPlane destination plane + * as a movement of the source object to be coincident with the destination object + * \param[in] theSourceSolid a shape to be moved + * \param[in] theDestSolid invariant shape + * \param[in] theSourceShape a shape on the solid to be made coincident with destination object + * \param[in] theDestShape destination object * \param[in] theIsReverse indicates that the solid materials should be on the same side against the destination plane * \param[in] theIsCentering indicates the planes should be centered */ - GEOMALGOAPI_EXPORT GeomAlgoAPI_Placement(std::shared_ptr theSourceShape, + GEOMALGOAPI_EXPORT GeomAlgoAPI_Placement(std::shared_ptr theSourceSolid, + std::shared_ptr theDestSolid, + std::shared_ptr theSourceShape, std::shared_ptr theDestShape, - std::shared_ptr theSourcePlane, - std::shared_ptr theDestPlane, bool theIsReverse = false, bool theIsCentering = false); @@ -62,10 +62,10 @@ public: private: /// builds resulting shape - void build(const std::shared_ptr& theSourceShape, + void build(const std::shared_ptr& theSourceSolid, + const std::shared_ptr& theDestSolid, + const std::shared_ptr& theSourceShape, const std::shared_ptr& theDestShape, - const std::shared_ptr& theSourcePlane, - const std::shared_ptr& theDestPlane, bool theIsReverse, bool theIsCentering);