+ data()->addAttribute(POINT3D(), GeomDataAPI_Point::typeId());
+
+ data()->addAttribute(CREATION_METHOD(), ModelAPI_AttributeString::typeId());
+
+ data()->addAttribute(INTERSECTION_LINE_1(), ModelAPI_AttributeSelection::typeId());
+ data()->addAttribute(INTERSECTION_LINE_2(), ModelAPI_AttributeSelection::typeId());
+
+ data()->addAttribute(INTERSECTION_LINE(), ModelAPI_AttributeSelection::typeId());
+ data()->addAttribute(INTERSECTION_PLANE(), ModelAPI_AttributeSelection::typeId());
+ data()->addAttribute(USE_OFFSET(), ModelAPI_AttributeString::typeId());
+ data()->addAttribute(OFFSET(), ModelAPI_AttributeDouble::typeId());
+ data()->addAttribute(REVERSE_OFFSET(), ModelAPI_AttributeBoolean::typeId());
+
+ data()->addAttribute(EDGE(), ModelAPI_AttributeSelection::typeId());
+ data()->addAttribute(OFFSET_TYPE(), ModelAPI_AttributeString::typeId());
+ data()->addAttribute(DISTANCE(), ModelAPI_AttributeDouble::typeId());
+ data()->addAttribute(RATIO(), ModelAPI_AttributeDouble::typeId());
+ data()->addAttribute(REVERSE(), ModelAPI_AttributeBoolean::typeId());
+
+ data()->addAttribute(POINT_TO_PROJECT(), ModelAPI_AttributeSelection::typeId());
+ data()->addAttribute(PROJECTION_TYPE(), ModelAPI_AttributeString::typeId());
+ data()->addAttribute(EDGE_FOR_POINT_PROJECTION(), ModelAPI_AttributeSelection::typeId());
+ data()->addAttribute(FACE_FOR_POINT_PROJECTION(), ModelAPI_AttributeSelection::typeId());
+
+ data()->addAttribute(INTERSECTION_TYPE(), ModelAPI_AttributeString::typeId());
+ data()->addAttribute(INTERSECTION_PLANE_1(), ModelAPI_AttributeSelection::typeId());
+ data()->addAttribute(INTERSECTION_PLANE_2(), ModelAPI_AttributeSelection::typeId());
+ data()->addAttribute(INTERSECTION_PLANE_3(), ModelAPI_AttributeSelection::typeId());
+
+ data()->addAttribute(GEOMETRICAL_PROPERTY_TYPE(), ModelAPI_AttributeString::typeId());
+ data()->addAttribute(OBJECT_FOR_CENTER_OF_GRAVITY(), ModelAPI_AttributeSelection::typeId());
+ data()->addAttribute(OBJECT_FOR_CENTER_OF_CIRCLE(), ModelAPI_AttributeSelection::typeId());
+}
+
+//==================================================================================================
+void ConstructionPlugin_Point::execute()
+{
+ GeomShapePtr aShape;
+
+ // to support compatibility with old documents where aCreationMethod did not exist
+ std::string aCreationMethod =
+ string(CREATION_METHOD()).get() && !string(CREATION_METHOD())->value().empty() ?
+ string(CREATION_METHOD())->value() : CREATION_METHOD_BY_XYZ();
+ if(aCreationMethod == CREATION_METHOD_BY_XYZ()) {
+ aShape = createByXYZ();
+ } else if(aCreationMethod == CREATION_METHOD_BY_DISTANCE_ON_EDGE()) {
+ aShape = createByDistanceOnEdge();
+ } else if(aCreationMethod == CREATION_METHOD_BY_PROJECTION()) {
+ if (string(PROJECTION_TYPE())->value() == PROJECTION_TYPE_ON_EDGE()) {
+ aShape = createByProjectionOnEdge();
+ } else {
+ aShape = createByProjectionOnFace();
+ }
+ } else if(aCreationMethod == CREATION_METHOD_BY_INTERSECTION()) {
+ std::string anIntersectionType = string(INTERSECTION_TYPE())->value();
+ if (anIntersectionType == INTERSECTION_TYPE_BY_LINES()) {
+ aShape = createByLinesIntersection();
+ } else if (anIntersectionType == INTERSECTION_TYPE_BY_LINE_AND_PLANE()) {
+ // this may produce several points
+ std::list<std::shared_ptr<GeomAPI_Vertex> > aPoints = createByLineAndPlaneIntersection();
+ if (!aPoints.empty()) { // if no points found produce the standard error later
+ int anIndex = 0;
+ std::list<std::shared_ptr<GeomAPI_Vertex> >::iterator aPIter = aPoints.begin();
+ for (; aPIter != aPoints.end(); aPIter++, anIndex++) {
+ std::shared_ptr<ModelAPI_ResultConstruction> aConstr =
+ document()->createConstruction(data(), anIndex);
+ aConstr->setShape(*aPIter);
+ setResult(aConstr, anIndex);
+ }
+ removeResults(anIndex);
+ return;
+ }
+ } else {
+ aShape = createByPlanesIntersection();
+ }
+ } else if (aCreationMethod == CREATION_METHOD_BY_GEOMETRICAL_PROPERTY()) {
+ std::string aGeometricalPropertyType = string(GEOMETRICAL_PROPERTY_TYPE())->value();
+ if (aGeometricalPropertyType == GEOMETRICAL_PROPERTY_TYPE_BY_CENTER_OF_GRAVITY()) {
+ aShape = createByCenterOfGravity();
+ } else {
+ aShape = createByCenterOfCircle();
+ }
+ }
+
+ if(!aShape.get()) {
+ setError("Error: intersection not found.");
+ return;
+ }
+
+ removeResults(1); // for case the point type was switched from multi-results type
+ std::shared_ptr<ModelAPI_ResultConstruction> aConstr = document()->createConstruction(data());
+ aConstr->setInfinite(true);
+ aConstr->setShape(aShape);
+ setResult(aConstr);
+}
+
+//==================================================================================================
+bool ConstructionPlugin_Point::customisePresentation(ResultPtr theResult,
+ AISObjectPtr thePrs)
+{
+ std::vector<int> aColor;
+ // get color from the attribute of the result
+ if (theResult.get() != NULL &&
+ theResult->data()->attribute(ModelAPI_Result::COLOR_ID()).get() != NULL) {
+ AttributeIntArrayPtr aColorAttr = theResult->data()->intArray(ModelAPI_Result::COLOR_ID());
+ if (aColorAttr.get() && aColorAttr->size()) {
+ aColor.push_back(aColorAttr->value(0));
+ aColor.push_back(aColorAttr->value(1));
+ aColor.push_back(aColorAttr->value(2));
+ }
+ }
+ if (aColor.empty())
+ aColor = Config_PropManager::color("Visualization", COLOR_NAME());
+
+ bool isCustomized = false;
+ if (aColor.size() == 3)
+ isCustomized = thePrs->setColor(aColor[0], aColor[1], aColor[2]);
+ //thePrs->setPointMarker(1, 1.); // Set point as a '+' symbol
+ return isCustomized;
+}
+
+//==================================================================================================
+std::shared_ptr<GeomAPI_Vertex> ConstructionPlugin_Point::createByXYZ()
+{
+ AttributePointPtr aPoint =
+ std::dynamic_pointer_cast<GeomDataAPI_Point>(data()->attribute(POINT3D()));
+ return GeomAlgoAPI_PointBuilder::vertex(aPoint->x(), aPoint->y(), aPoint->z());
+}
+
+//==================================================================================================
+std::shared_ptr<GeomAPI_Vertex> ConstructionPlugin_Point::createByDistanceOnEdge()
+{
+ // Get edge.
+ AttributeSelectionPtr anEdgeSelection = selection(EDGE());
+ GeomShapePtr aShape = anEdgeSelection->value();
+ if(!aShape.get()) {
+ aShape = anEdgeSelection->context()->shape();
+ }
+ std::shared_ptr<GeomAPI_Edge> anEdge(new GeomAPI_Edge(aShape));
+
+ // Get distance value and percent flag.
+ double aValue;
+ bool anIsPercent = false;
+ if (string(OFFSET_TYPE())->value() == OFFSET_TYPE_BY_DISTANCE()) {
+ aValue = real(DISTANCE())->value();
+ anIsPercent = false;
+ } else {
+ aValue = real(RATIO())->value() * 100.0;
+ anIsPercent = true;
+ }
+
+ // Get reverse flag.
+ bool anIsReverse = boolean(REVERSE())->value();
+
+ return GeomAlgoAPI_PointBuilder::vertexOnEdge(anEdge, aValue, anIsPercent, anIsReverse);
+}
+
+//==================================================================================================
+std::shared_ptr<GeomAPI_Vertex> ConstructionPlugin_Point::createByProjectionOnEdge()
+{
+ // Get point.
+ AttributeSelectionPtr aPointSelection = selection(POINT_TO_PROJECT());
+ GeomShapePtr aPointShape = aPointSelection->value();
+ if (!aPointShape.get()) {
+ aPointShape = aPointSelection->context()->shape();
+ }
+ std::shared_ptr<GeomAPI_Vertex> aVertex(new GeomAPI_Vertex(aPointShape));
+
+ // Get edge.
+ AttributeSelectionPtr anEdgeSelection = selection(EDGE_FOR_POINT_PROJECTION());
+ GeomShapePtr anEdgeShape = anEdgeSelection->value();
+ if (!anEdgeShape.get()) {
+ anEdgeShape = anEdgeSelection->context()->shape();
+ }
+ std::shared_ptr<GeomAPI_Edge> anEdge(new GeomAPI_Edge(anEdgeShape));
+
+ return GeomAlgoAPI_PointBuilder::vertexByProjection(aVertex, anEdge);
+}
+
+//==================================================================================================
+std::shared_ptr<GeomAPI_Vertex> ConstructionPlugin_Point::createByProjectionOnFace()
+{
+ // Get point.
+ AttributeSelectionPtr aPointSelection = selection(POINT_TO_PROJECT());
+ GeomShapePtr aPointShape = aPointSelection->value();
+ if(!aPointShape.get()) {
+ aPointShape = aPointSelection->context()->shape();
+ }
+ std::shared_ptr<GeomAPI_Vertex> aVertex(new GeomAPI_Vertex(aPointShape));
+
+ // Get plane.
+ AttributeSelectionPtr aPlaneSelection = selection(FACE_FOR_POINT_PROJECTION());
+ GeomShapePtr aPlaneShape = aPlaneSelection->value();
+ if(!aPlaneShape.get()) {
+ aPlaneShape = aPlaneSelection->context()->shape();
+ }
+ std::shared_ptr<GeomAPI_Face> aFace(new GeomAPI_Face(aPlaneShape));
+
+ return GeomAlgoAPI_PointBuilder::vertexByProjection(aVertex, aFace);
+}
+
+//==================================================================================================
+std::shared_ptr<GeomAPI_Vertex> ConstructionPlugin_Point::createByLinesIntersection()
+{
+ // Get first line.
+ AttributeSelectionPtr aFirstLineSelection= selection(INTERSECTION_LINE_1());
+ GeomShapePtr aFirstLineShape = aFirstLineSelection->value();
+ if(!aFirstLineShape.get()) {
+ aFirstLineShape = aFirstLineSelection->context()->shape();
+ }
+ std::shared_ptr<GeomAPI_Edge> aFirstEdge(new GeomAPI_Edge(aFirstLineShape));
+
+ // Get second line.
+ AttributeSelectionPtr aSecondLineSelection= selection(INTERSECTION_LINE_2());
+ GeomShapePtr aSecondLineShape = aSecondLineSelection->value();
+ if(!aSecondLineShape.get()) {
+ aSecondLineShape = aSecondLineSelection->context()->shape();
+ }
+ std::shared_ptr<GeomAPI_Edge> aSecondEdge(new GeomAPI_Edge(aSecondLineShape));
+
+ return GeomAlgoAPI_PointBuilder::vertexByIntersection(aFirstEdge, aSecondEdge);