#include <Config_PropManager.h>
+#include <ModelAPI_AttributeBoolean.h>
#include <ModelAPI_AttributeSelection.h>
#include <ModelAPI_ResultConstruction.h>
#include <ModelAPI_AttributeString.h>
#include <ModelAPI_Validator.h>
#include <GeomAPI_Edge.h>
+#include <GeomAPI_Lin.h>
#include <GeomAPI_Pln.h>
#include <GeomAPI_Vertex.h>
#include <GeomAlgoAPI_EdgeBuilder.h>
using namespace std;
+static const double defaultAxisSize = 50;
+
ConstructionPlugin_Axis::ConstructionPlugin_Axis()
{
}
/// Attributes for axis by plane and point.
data()->addAttribute(PLANE(), ModelAPI_AttributeSelection::typeId());
data()->addAttribute(POINT(), ModelAPI_AttributeSelection::typeId());
+
+ /// Attributes for axis by two planes.
+ data()->addAttribute(PLANE1(), ModelAPI_AttributeSelection::typeId());
+ data()->addAttribute(USE_OFFSET1(), ModelAPI_AttributeString::typeId());
+ data()->addAttribute(OFFSET1(), ModelAPI_AttributeDouble::typeId());
+ data()->addAttribute(REVERSE_OFFSET1(), ModelAPI_AttributeBoolean::typeId());
+ data()->addAttribute(PLANE2(), ModelAPI_AttributeSelection::typeId());
+ data()->addAttribute(USE_OFFSET2(), ModelAPI_AttributeString::typeId());
+ data()->addAttribute(OFFSET2(), ModelAPI_AttributeDouble::typeId());
+ data()->addAttribute(REVERSE_OFFSET2(), ModelAPI_AttributeBoolean::typeId());
}
void ConstructionPlugin_Axis::createAxisByTwoPoints()
std::shared_ptr<GeomAPI_Pnt> aProjPnt = aPln->project(aPnt);
if(aProjPnt->isEqual(aPnt)) {
- aPnt->translate(aPln->direction(), 10);
+ aPnt->translate(aPln->direction(), defaultAxisSize);
}
std::shared_ptr<GeomAPI_Edge> anEdge = GeomAlgoAPI_EdgeBuilder::line(aProjPnt, aPnt);
setResult(aConstr);
}
+void ConstructionPlugin_Axis::createAxisByTwoPlanes()
+{
+ // Get face 1.
+ AttributeSelectionPtr aFaceSelection1 = selection(PLANE1());
+ GeomShapePtr aFaceShape1 = aFaceSelection1->value();
+ if(!aFaceShape1.get()) {
+ aFaceShape1 = aFaceSelection1->context()->shape();
+ }
+ std::shared_ptr<GeomAPI_Face> aFace1(new GeomAPI_Face(aFaceShape1));
+ std::shared_ptr<GeomAPI_Pln> aPln1 = aFace1->getPlane();
+
+ std::string useOffset1 = string(USE_OFFSET1())->value();
+ if(!useOffset1.empty()) {
+ double anOffset1 = real(OFFSET1())->value();
+ bool reverseOffset1 = boolean(REVERSE_OFFSET1())->value();
+ if(reverseOffset1) {
+ anOffset1 = -anOffset1;
+ }
+ aPln1->translate(aPln1->direction(), anOffset1);
+ }
+
+ // Get face 2.
+ AttributeSelectionPtr aFaceSelection2 = selection(PLANE2());
+ GeomShapePtr aFaceShape2 = aFaceSelection2->value();
+ if(!aFaceShape2.get()) {
+ aFaceShape2 = aFaceSelection2->context()->shape();
+ }
+ std::shared_ptr<GeomAPI_Face> aFace2(new GeomAPI_Face(aFaceShape2));
+ std::shared_ptr<GeomAPI_Pln> aPln2 = aFace2->getPlane();
+
+ std::string useOffset2 = string(USE_OFFSET2())->value();
+ if(!useOffset2.empty()) {
+ double anOffset2 = real(OFFSET2())->value();
+ bool reverseOffset2 = boolean(REVERSE_OFFSET2())->value();
+ if(reverseOffset2) {
+ anOffset2 = -anOffset2;
+ }
+ aPln2->translate(aPln2->direction(), anOffset2);
+ }
+
+ std::shared_ptr<GeomAPI_Lin> aLin = aPln1->intersect(aPln2);
+ std::shared_ptr<GeomAPI_Pnt> aPnt1 = aLin->location();
+ std::shared_ptr<GeomAPI_Pnt> aPnt2 = aLin->location();
+ aPnt2->translate(aLin->direction(), defaultAxisSize);
+
+ std::shared_ptr<GeomAPI_Edge> anEdge = GeomAlgoAPI_EdgeBuilder::line(aPnt1, aPnt2);
+
+ ResultConstructionPtr aConstr = document()->createConstruction(data());
+ aConstr->setInfinite(true);
+ aConstr->setShape(anEdge);
+ setResult(aConstr);
+}
+
void ConstructionPlugin_Axis::execute()
{
AttributeStringPtr aMethodTypeAttr = string(ConstructionPlugin_Axis::METHOD());
createAxisByLine();
} else if(aMethodType == CREATION_METHOD_BY_PLANE_AND_POINT()) {
createAxisByPlaneAndPoint();
+ } else if(aMethodType == CREATION_METHOD_BY_TWO_PLANES()) {
+ createAxisByTwoPlanes();
}
}
return METHOD_ATTR;
}
+ /// Attribute name for creation method.
+ inline static const std::string& CREATION_METHOD_BY_TWO_PLANES()
+ {
+ static const std::string METHOD_ATTR("by_two_planes");
+ return METHOD_ATTR;
+ }
+
/// attribute name for first point
inline static const std::string& POINT_FIRST()
{
return ATTR_ID;
}
+ /// Attribute name for plane 1.
+ inline static const std::string& PLANE1()
+ {
+ static const std::string ATTR_ID("plane1");
+ return ATTR_ID;
+ }
+
+ /// Attribute name for use offset for plane 1.
+ inline static const std::string& USE_OFFSET1()
+ {
+ static const std::string ATTR_ID("use_offset1");
+ return ATTR_ID;
+ }
+
+ /// Attribute name for offset for plane 1.
+ inline static const std::string& OFFSET1()
+ {
+ static const std::string ATTR_ID("offset1");
+ return ATTR_ID;
+ }
+
+ /// Attribute name for reverse offset for plane 1.
+ inline static const std::string& REVERSE_OFFSET1()
+ {
+ static const std::string ATTR_ID("reverse_offset1");
+ return ATTR_ID;
+ }
+
+ /// Attribute name for plane 2.
+ inline static const std::string& PLANE2()
+ {
+ static const std::string ATTR_ID("plane2");
+ return ATTR_ID;
+ }
+
+ /// Attribute name for use offset for plane 2.
+ inline static const std::string& USE_OFFSET2()
+ {
+ static const std::string ATTR_ID("use_offset2");
+ return ATTR_ID;
+ }
+
+ /// Attribute name for offset for plane 2.
+ inline static const std::string& OFFSET2()
+ {
+ static const std::string ATTR_ID("offset2");
+ return ATTR_ID;
+ }
+
+ /// Attribute name for reverse offset for plane 2.
+ inline static const std::string& REVERSE_OFFSET2()
+ {
+ static const std::string ATTR_ID("reverse_offset2");
+ return ATTR_ID;
+ }
+
/// Returns a minimal length for axis
inline static const double MINIMAL_LENGTH() { return 1.e-5; }
void createAxisByPointAndDirection();
void createAxisByLine();
void createAxisByPlaneAndPoint();
+ void createAxisByTwoPlanes();
};
new ConstructionPlugin_ValidatorPlaneLinePoint());
aFactory->registerValidator("ConstructionPlugin_ValidatorPlaneTwoParallelPlanes",
new ConstructionPlugin_ValidatorPlaneTwoParallelPlanes());
+ aFactory->registerValidator("ConstructionPlugin_ValidatorAxisTwoNotParallelPlanes",
+ new ConstructionPlugin_ValidatorAxisTwoNotParallelPlanes());
// register this plugin
ModelAPI_Session::get()->registerPlugin(this);
return true;
}
+//==================================================================================================
+bool ConstructionPlugin_ValidatorAxisTwoNotParallelPlanes::isValid(
+ const AttributePtr& theAttribute,
+ const std::list<std::string>& theArguments,
+ Events_InfoMessage& theError) const
+{
+ FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
+
+ AttributeSelectionPtr anAttribute1 = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
+ AttributeSelectionPtr anAttribute2 = aFeature->selection(theArguments.front());
+
+ std::shared_ptr<GeomAPI_Pln> aPln1;
+ std::shared_ptr<GeomAPI_Pln> aPln2;
+
+ GeomShapePtr aShape1 = anAttribute1->value();
+ ResultPtr aContext1 = anAttribute1->context();
+ if(!aContext1.get()) {
+ theError = "One of the attribute not initialized.";
+ return false;
+ }
+ if(!aShape1.get()) {
+ aShape1 = aContext1->shape();
+ }
+
+ GeomShapePtr aShape2 = anAttribute2->value();
+ ResultPtr aContext2 = anAttribute2->context();
+ if(!aContext2.get()) {
+ return true;
+ }
+ if(!aShape2.get()) {
+ aShape2 = aContext2->shape();
+ }
+
+ aPln1 = getPln(aShape1);
+ aPln2 = getPln(aShape2);
+
+ if(!aPln1.get() || !aPln2.get()) {
+ theError = "Wrong shape types selected.";
+ return false;
+ }
+
+ std::shared_ptr<GeomAPI_Dir> aDir1 = aPln1->direction();
+ std::shared_ptr<GeomAPI_Dir> aDir2 = aPln2->direction();
+
+ if(aDir1->isParallel(aDir2)) {
+ theError = "Planes are parallel.";
+ return false;
+ }
+
+ return true;
+}
+
std::shared_ptr<GeomAPI_Lin> getLin(const GeomShapePtr theShape)
{
std::shared_ptr<GeomAPI_Lin> aLin;
Events_InfoMessage& theError) const;
};
+/// \class ConstructionPlugin_ValidatorAxisTwoNotParallelPlanes
+/// \ingroup Validators
+/// \brief A validator for selection two parallel planes.
+class ConstructionPlugin_ValidatorAxisTwoNotParallelPlanes: public ModelAPI_AttributeValidator
+{
+public:
+ //! \return True if the attribute is valid.
+ //! \param[in] theAttribute the checked attribute.
+ //! \param[in] theArguments arguments of the attribute.
+ //! \param[out] theError error message.
+ virtual bool isValid(const AttributePtr& theAttribute,
+ const std::list<std::string>& theArguments,
+ Events_InfoMessage& theError) const;
+};
+
#endif
\ No newline at end of file
shape_types="vertex">
</shape_selector>
</box>
+ <box id="by_two_planes" title="By two planes" icon="icons/Construction/axis_by_two_planes_32x32.png">
+ <shape_selector id="plane1"
+ label="1st plane"
+ tooltip="Select a planar face."
+ icon="icons/Construction/face.png"
+ shape_types="face">
+ <validator id="GeomValidators_Face" parameters="plane"/>
+ <validator id="ConstructionPlugin_ValidatorAxisTwoNotParallelPlanes" parameters="plane2"/>
+ </shape_selector>
+ <optionalbox id="use_offset1" title="Offset from 1st plane">
+ <doublevalue id="offset1" label="Distance " tooltip="Distance value" min="0" default="0"/>
+ <boolvalue id="reverse_offset1" label="Reverse" tooltip="Reverse offset value" default="false"/>
+ </optionalbox>
+ <shape_selector id="plane2"
+ label="2nd plane"
+ tooltip="Select a planar face."
+ icon="icons/Construction/face.png"
+ shape_types="face">
+ <validator id="GeomValidators_Face" parameters="plane"/>
+ <validator id="ConstructionPlugin_ValidatorAxisTwoNotParallelPlanes" parameters="plane1"/>
+ </shape_selector>
+ <optionalbox id="use_offset2" title="Offset from 2nd plane">
+ <doublevalue id="offset2" label="Distance " tooltip="Distance value" min="0" default="0"/>
+ <boolvalue id="reverse_offset2" label="Reverse" tooltip="Reverse offset value" default="false"/>
+ </optionalbox>
+ </box>
</toolbox>
</source>
#include <gp_Pln.hxx>
+#include <IntAna_QuadQuadGeo.hxx>
+
using namespace std;
GeomAPI_Pln::GeomAPI_Pln(const std::shared_ptr<GeomAPI_Ax3>& theAxis)
return aMyPln.Distance(anOtherPln);
}
+
+void GeomAPI_Pln::translate(const std::shared_ptr<GeomAPI_Dir> theDir, double theDist)
+{
+ gp_Vec aVec(theDir->impl<gp_Dir>());
+ aVec.Normalize();
+ aVec.Multiply(theDist);
+ implPtr<gp_Pln>()->Translate(aVec);
+}
+
+std::shared_ptr<GeomAPI_Lin> GeomAPI_Pln::intersect(const std::shared_ptr<GeomAPI_Pln> thePlane) const
+{
+ std::shared_ptr<GeomAPI_Lin> aRes;
+
+ if(!thePlane.get()) {
+ return aRes;
+ }
+
+ const gp_Pln& aMyPln = impl<gp_Pln>();
+ const gp_Pln& anOtherPln = thePlane->impl<gp_Pln>();
+
+ IntAna_QuadQuadGeo aQuad(aMyPln, anOtherPln, Precision::Confusion(), Precision::Confusion());
+
+ if(aQuad.IsDone() != Standard_True) {
+ return aRes;
+ }
+
+ if(aQuad.NbSolutions() != 1) {
+ return aRes;
+ }
+
+ gp_Lin aLin = aQuad.Line(1);
+ gp_Pnt aLoc = aLin.Location();
+ gp_Dir aDir = aLin.Direction();
+
+ std::shared_ptr<GeomAPI_Pnt> aGeomLoc(new GeomAPI_Pnt(aLoc.X(), aLoc.Y(), aLoc.Z()));
+ std::shared_ptr<GeomAPI_Dir> aGeomDir(new GeomAPI_Dir(aDir.X(), aDir.Y(), aDir.Z()));
+
+ aRes.reset(new GeomAPI_Lin(aGeomLoc, aGeomDir));
+
+ return aRes;
+}
/// \return distance between planes.
GEOMAPI_EXPORT
double distance(const std::shared_ptr<GeomAPI_Pln> thePlane) const;
+
+ /// Translates the plane along direction theDir on distance theDist
+ GEOMAPI_EXPORT
+ void translate(const std::shared_ptr<GeomAPI_Dir> theDir, const double theDist);
+
+ /// \return intersection line of two planes. Empty if they are parallel.
+ GEOMAPI_EXPORT
+ std::shared_ptr<GeomAPI_Lin> intersect(const std::shared_ptr<GeomAPI_Pln> thePlane) const;
};
#endif