def createPoint(theSketchFeature):
aSketchPointFeature = theSketchFeature.addFeature("SketchPoint")
- aPointCoordindates = geomDataAPI_Point2D(aSketchPointFeature.attribute("PointCoordindates"))
- aPointCoordindates.setValue(random.uniform(0, 50), random.uniform(0, 50))
+ aPointCoordinates = geomDataAPI_Point2D(aSketchPointFeature.attribute("PointCoordinates"))
+ aPointCoordinates.setValue(random.uniform(0, 50), random.uniform(0, 50))
return aSketchPointFeature
def createLine(theSketchFeature):
def createPoint(theSketchFeature):
aSketchPointFeature = theSketchFeature.addFeature("SketchPoint")
- aPointCoordindates = geomDataAPI_Point2D(aSketchPointFeature.attribute("PointCoordindates"))
- aPointCoordindates.setValue(random.uniform(0, 100), random.uniform(0, 100))
+ aPointCoordinates = geomDataAPI_Point2D(aSketchPointFeature.attribute("PointCoordinates"))
+ aPointCoordinates.setValue(random.uniform(0, 100), random.uniform(0, 100))
return aSketchPointFeature
# Get document
norm.setValue(0, 0, 1)
# Create circle
aSketchCircle = aCircleSketchFeature.addFeature("SketchCircle")
-anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("CircleCenter"))
-aCircleRadius = aSketchCircle.real("CircleRadius")
+anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("circle_center"))
+aCircleRadius = aSketchCircle.real("circle_radius")
anCircleCentr.setValue(0., 57.74)
aCircleRadius.setValue(50.)
aSession.finishOperation()
norm.setValue(0, 0, 1)
# Create circle
aSketchCircle = aCircleSketchFeature.addFeature("SketchCircle")
-anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("CircleCenter"))
-aCircleRadius = aSketchCircle.real("CircleRadius")
+anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("circle_center"))
+aCircleRadius = aSketchCircle.real("circle_radius")
anCircleCentr.setValue(0, 0)
aCircleRadius.setValue(50)
aSession.finishOperation()
{
if (!myFlushActive)
return;
+ bool hasEventsToFlush = !myGroups.empty();
std::map<char*, std::shared_ptr<Events_Message> >::iterator aMyGroup;
for(aMyGroup = myGroups.find(theID.eventText());
aMyGroup != myGroups.end(); aMyGroup = myGroups.find(theID.eventText()))
}
}
}
+ if (hasEventsToFlush && myGroups.empty() && myFlushed.empty()) {
+ // no more messages left in the queue, so, finalize the sketch processing
+ static Events_ID anID = Events_Loop::eventByName("SketchPrepared");
+ std::shared_ptr<Events_Message> aMsg(new Events_Message(anID, this));
+ Events_Loop::loop()->send(aMsg, false);
+ }
}
void Events_Loop::eraseMessages(const Events_ID& theID)
}
}
-void Events_Loop::autoFlush(const Events_ID& theID, const bool theAuto)
-{
- if (theAuto)
- myFlushed.insert(theID.myID);
- else
- myFlushed.erase(myFlushed.find(theID.myID));
-}
-
bool Events_Loop::isFlushed(const Events_ID& theID)
{
return myFlushed.find(theID.myID) != myFlushed.end();
else
myFlushed.erase(myFlushed.find(theID.myID));
}
+
+bool Events_Loop::hasGrouppedEvent(const Events_ID& theID)
+{
+ return myGroups.find(theID.myID) != myGroups.end();
+}
\ No newline at end of file
//! Clears all collected messages
EVENTS_EXPORT void clear(const Events_ID& theID);
- //! Enables flush without grouping for the given message
- EVENTS_EXPORT void autoFlush(const Events_ID& theID, const bool theAuto = true);
-
//! Returns true if the evement is flushed right now
EVENTS_EXPORT bool isFlushed(const Events_ID& theID);
//! Sets the flag that the event is flished right now
EVENTS_EXPORT void setFlushed(const Events_ID& theID, const bool theValue);
+ //! Returns true if a loop accumulated events to be flashed
+ EVENTS_EXPORT bool hasGrouppedEvent(const Events_ID& theID);
+
private:
//! Calls "processEvent" for the given listeners.
//! If theFlushedNow for grouped listeners is stores message in listeners.
aDumper->clear();
DocumentPtr aDoc = ModelAPI_Session::get()->moduleDocument();
+ int aFeaturesNb = aDoc->size(ModelAPI_Feature::group());
+ if(aFeaturesNb > 1) {
+ FeaturePtr aLastFeature =
+ ModelAPI_Feature::feature(aDoc->object(ModelAPI_Feature::group(), aFeaturesNb - 1));
+ if(aDoc->currentFeature(true) != aLastFeature) {
+ setError("Dump cannot be done. Please move the history line to the end before dumping.");
+ return;
+ }
+ }
+
+ DocumentPtr anActiveDoc = ModelAPI_Session::get()->activeDocument();
+ aFeaturesNb = anActiveDoc->size(ModelAPI_Feature::group());
+ if(aFeaturesNb > 1) {
+ FeaturePtr aLastFeature =
+ ModelAPI_Feature::feature(anActiveDoc->object(ModelAPI_Feature::group(), aFeaturesNb - 1));
+ if(anActiveDoc->currentFeature(true) != aLastFeature) {
+ setError("Dump cannot be done. Please move the history line to the end before dumping.");
+ return;
+ }
+ }
+
std::list<FeaturePtr> aFeatures = aDoc->allFeatures();
for(std::list<FeaturePtr>::const_iterator aFeatIt = aFeatures.begin();
aFeatIt != aFeatures.end();
Test1942.py
Test1915.py
Test2023.py
+ Test2046.py
+ Test2038.py
)
std::shared_ptr<GeomAPI_DataMapOfShapeShape> aMapOfSubShapes = theMakeShape->mapOfSubShapes();
switch(aBaseShapeType) {
- case GeomAPI_Shape::EDGE:
+ case GeomAPI_Shape::EDGE: {
+ aShapeTypeToExplode = GeomAPI_Shape::VERTEX;
+ break;
+ }
case GeomAPI_Shape::WIRE: {
//std::shared_ptr<GeomAPI_Vertex> aV1, aV2;
//GeomAlgoAPI_ShapeTools::findBounds(theBaseShape, aV1, aV2);
//if(!aV2History.empty()) {
// theResultBody->generated(aV2, aV2History.front(), aGenName + "Edge_2", theTag++);
//}
- aShapeTypeToExplode = GeomAPI_Shape::VERTEX;
+ aShapeTypeToExplode = GeomAPI_Shape::COMPOUND;
break;
}
case GeomAPI_Shape::FACE:
case GeomAPI_Shape::SHELL: {
theResultBody->loadAndOrientModifiedShapes(&theAlgo,
theBaseShape, GeomAPI_Shape::FACE,
- theFaceTag, theName + "_Face", theSubShapes);
+ theFaceTag, theName + "_Face", theSubShapes, false, true);
if (theBaseShape->shapeType() == GeomAPI_Shape::COMPSOLID
|| theBaseShape->shapeType() == GeomAPI_Shape::SOLID) {
break;
case GeomAPI_Shape::WIRE: {
theResultBody->loadAndOrientModifiedShapes(&theAlgo,
theBaseShape, GeomAPI_Shape::EDGE,
- theEdgeTag, theName + "_Edge", theSubShapes);
+ theEdgeTag, theName + "_Edge", theSubShapes, false, true);
}
case GeomAPI_Shape::EDGE: {
theResultBody->loadAndOrientModifiedShapes(&theAlgo,
theBaseShape, GeomAPI_Shape::VERTEX,
- theVertexTag, theName + "_Vertex", theSubShapes);
+ theVertexTag, theName + "_Vertex", theSubShapes, false, true);
}
}
}
--- /dev/null
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(-379.073756432247, 108.9193825042881, -672.3842195540308, -33.44768439108059)
+SketchLine_2 = Sketch_1.addLine(-672.3842195540308, -33.44768439108059, -360.2058319039451, -146.6552315608919)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(-360.2058319039451, -146.6552315608919, -78.9022298456261, -14.57975986277871)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchLine_4 = Sketch_1.addLine(-78.9022298456261, -14.57975986277871, -379.073756432247, 108.9193825042881)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchLine_4.endPoint())
+SketchLine_5 = Sketch_1.addLine(-379.073756432247, 108.9193825042881, -360.2058319039451, -146.6552315608919)
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchLine_5.startPoint())
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_5.endPoint())
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_1f-SketchLine_2f-SketchLine_5r")], model.selection(), 100, 0)
+Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_3f-SketchLine_4f-SketchLine_5f")], model.selection(), 100, 0)
+Translation_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Extrusion_1_1")], model.selection("EDGE", "PartSet/OX"), 50)
+Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Translation_1_1"), model.selection("SOLID", "Extrusion_2_1")])
+Translation_2 = model.addTranslation(Part_1_doc, [model.selection("COMPSOLID", "Partition_1_1")], model.selection("EDGE", "PartSet/OZ"), 50)
+Group_1 = model.addGroup(Part_1_doc, [model.selection("FACE", "Translation_2_1/Translated_Face_24"), model.selection("FACE", "Translation_2_1/Translated_Face_13"), model.selection("FACE", "Translation_2_1/Translated_Face_16"), model.selection("FACE", "Translation_2_1/Translated_Face_12"), model.selection("FACE", "Translation_2_1/Translated_Face_9"), model.selection("FACE", "Translation_2_1/Translated_Face_10"), model.selection("FACE", "Translation_2_1/Translated_Face_11"), model.selection("FACE", "Translation_2_1/Translated_Face_25"), model.selection("FACE", "Translation_2_1/Translated_Face_20"), model.selection("FACE", "Translation_2_1/Translated_Face_19"), model.selection("FACE", "Translation_2_1/Translated_Face_18"), model.selection("FACE", "Translation_2_1/Translated_Face_27"), model.selection("FACE", "Translation_2_1/Translated_Face_17"), model.selection("FACE", "Translation_2_1/Translated_Face_31"), model.selection("FACE", "Translation_2_1/Translated_Face_32"), model.selection("FACE", "Translation_2_1/Translated_Face_30"), model.selection("FACE", "Translation_2_1/Translated_Face_28"), model.selection("FACE", "Translation_2_1/Translated_Face_29"), model.selection("FACE", "Translation_2_1/Translated_Face_8"), model.selection("FACE", "Translation_2_1/Translated_Face_22"), model.selection("FACE", "Translation_2_1/Translated_Face_7"), model.selection("FACE", "Translation_2_1/Translated_Face_6"), model.selection("FACE", "Translation_2_1/Translated_Face_5"), model.selection("FACE", "Translation_2_1/Translated_Face_3"), model.selection("FACE", "Translation_2_1/Translated_Face_1"), model.selection("FACE", "Translation_2_1/Translated_Face_2"), model.selection("FACE", "Translation_2_1/Translated_Face_21"), model.selection("FACE", "Translation_2_1/Translated_Face_4"), model.selection("FACE", "Translation_2_1/Translated_Face_25"), model.selection("FACE", "Translation_2_1/Translated_Face_27"), model.selection("FACE", "Translation_2_1/Translated_Face_21"), model.selection("FACE", "Translation_2_1/Translated_Face_22"), model.selection("FACE", "Translation_2_1/Translated_Face_26"), model.selection("FACE", "Translation_2_1/Translated_Face_23"), model.selection("FACE", "Translation_2_1/Translated_Face_30"), model.selection("FACE", "Translation_2_1/Translated_Face_23"), model.selection("FACE", "Translation_2_1/Translated_Face_14"), model.selection("FACE", "Translation_2_1/Translated_Face_15")])
+model.do()
+model.end()
+
+groupFeature = Group_1.feature()
+groupSelectionList = groupFeature.selectionList("group_list")
+for index in range(0, groupSelectionList.size()):
+ attrSelection = groupSelectionList.value(index)
+ shape = attrSelection.value()
+ name = attrSelection.namingName()
+ assert(shape.isFace())
+ assert(name != ""), "Empty shape name"
--- /dev/null
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Sketch_1 = model.addSketch(partSet, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(-1154.716981132076, -199.5283018867925, -849.0566037735849, 128.7735849056603)
+SketchLine_2 = Sketch_1.addLine(-849.0566037735849, 128.7735849056603, -563.2075471698113, -69.33962264150945)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(-563.2075471698113, -69.33962264150945, -70.75471698113215, 326.8867924528301)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+model.do()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Wire_1 = model.addWire(Part_1_doc, [model.selection("EDGE", "PartSet/Sketch_1/Edge-SketchLine_1"), model.selection("EDGE", "PartSet/Sketch_1/Edge-SketchLine_2"), model.selection("EDGE", "PartSet/Sketch_1/Edge-SketchLine_3")])
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("WIRE", "Wire_1_1")], model.selection(), 100, 0)
+Group_1 = model.addGroup(Part_1_doc, [model.selection("FACE", "Extrusion_1_1/Generated_Face_3"), model.selection("FACE", "Extrusion_1_1/Generated_Face_2"), model.selection("FACE", "Extrusion_1_1/Generated_Face_1")])
+model.do()
+model.end()
+
+groupFeature = Group_1.feature()
+groupSelectionList = groupFeature.selectionList("group_list")
+assert(groupSelectionList.size() == 3)
+for index in range(0, groupSelectionList.size()):
+ attrSelection = groupSelectionList.value(index)
+ shape = attrSelection.value()
+ name = attrSelection.namingName()
+ assert(shape.isFace())
+ assert(name != ""), "Empty shape name"
norm = geomDataAPI_Dir(aCircleSketchFeature.attribute("Norm"))
norm.setValue(0, 0, 1)
aSketchCircle = aCircleSketchFeature.addFeature("SketchCircle")
-anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("CircleCenter"))
-aCircleRadius = aSketchCircle.real("CircleRadius")
+anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("circle_center"))
+aCircleRadius = aSketchCircle.real("circle_radius")
anCircleCentr.setValue(10., 10.)
aCircleRadius.setValue(50.)
aSession.finishOperation()
norm.setValue(0, 0, 1)
aSketchCircle = aCircleSketchFeature.addFeature("SketchCircle")
-aCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("CircleCenter"))
-aCircleRadius = aSketchCircle.real("CircleRadius")
+aCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("circle_center"))
+aCircleRadius = aSketchCircle.real("circle_radius")
aCircleCentr.setValue(0, 0)
aCircleRadius.setValue(50)
norm = geomDataAPI_Dir(aCircleSketchFeature.attribute("Norm"))
norm.setValue(0, 0, 1)
aSketchCircle = aCircleSketchFeature.addFeature("SketchCircle")
-anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("CircleCenter"))
-aCircleRadius = aSketchCircle.real("CircleRadius")
+anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("circle_center"))
+aCircleRadius = aSketchCircle.real("circle_radius")
anCircleCentr.setValue(10., 10.)
aCircleRadius.setValue(50.)
aSession.finishOperation()
norm.setValue(0, 0, 1)
aSketchCircle = aCircleSketchFeature.addFeature("SketchCircle")
-aCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("CircleCenter"))
-aCircleRadius = aSketchCircle.real("CircleRadius")
+aCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("circle_center"))
+aCircleRadius = aSketchCircle.real("circle_radius")
aCircleCentr.setValue(0, 0)
aCircleRadius.setValue(50)
aCircleSketchFeature.selection("External").selectSubShape("face", "Extrusion_1/To_Face_1")
aSession.startOperation()
aSketchCircle = aCircleSketchFeature.addFeature("SketchCircle")
-anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("CircleCenter"))
-aCircleRadius = aSketchCircle.real("CircleRadius")
+anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("circle_center"))
+aCircleRadius = aSketchCircle.real("circle_radius")
anCircleCentr.setValue(0, 0)
aCircleRadius.setValue(10)
aSession.finishOperation()
aCircleSketchFeature.selection("External").selectSubShape("face", "Extrusion_1/To_Face_1")
aSession.startOperation()
aSketchCircle = aCircleSketchFeature.addFeature("SketchCircle")
-anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("CircleCenter"))
-aCircleRadius = aSketchCircle.real("CircleRadius")
+anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("circle_center"))
+aCircleRadius = aSketchCircle.real("circle_radius")
anCircleCentr.setValue(0, 0)
aCircleRadius.setValue(10)
aSession.finishOperation()
norm.setValue(0, 0, 1)
# Create circle
aSketchCircle = aCircleSketchFeature.addFeature("SketchCircle")
-anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("CircleCenter"))
-aCircleRadius = aSketchCircle.real("CircleRadius")
+anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("circle_center"))
+aCircleRadius = aSketchCircle.real("circle_radius")
anCircleCentr.setValue(50., 50)
aCircleRadius.setValue(20.)
aSession.finishOperation()
norm.setValue(0, 0, 1)
# Create circle
aSketchCircle = aCircleSketchFeature.addFeature("SketchCircle")
-anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("CircleCenter"))
-aCircleRadius = aSketchCircle.real("CircleRadius")
+anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("circle_center"))
+aCircleRadius = aSketchCircle.real("circle_radius")
anCircleCentr.setValue(0, 0)
aCircleRadius.setValue(20)
aSession.finishOperation()
aCircleSketchFeature.selection("External").selectSubShape("face", "Extrusion_1/To_Face_1")
aSession.startOperation()
aSketchCircle = aCircleSketchFeature.addFeature("SketchCircle")
-anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("CircleCenter"))
-aCircleRadius = aSketchCircle.real("CircleRadius")
+anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("circle_center"))
+aCircleRadius = aSketchCircle.real("circle_radius")
anCircleCentr.setValue(0, 0)
aCircleRadius.setValue(10)
aSession.finishOperation()
norm.setValue(0, 0, 1)
# Create circle
aSketchCircle = aCircleSketchFeature.addFeature("SketchCircle")
-anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("CircleCenter"))
-aCircleRadius = aSketchCircle.real("CircleRadius")
+anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("circle_center"))
+aCircleRadius = aSketchCircle.real("circle_radius")
anCircleCentr.setValue(0, 0)
aCircleRadius.setValue(20)
aSession.finishOperation()
aCircleSketchFeature.selection("External").selectSubShape("face", "Extrusion_1/To_Face_1")
aSession.startOperation()
aSketchCircle = aCircleSketchFeature.addFeature("SketchCircle")
-anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("CircleCenter"))
-aCircleRadius = aSketchCircle.real("CircleRadius")
+anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("circle_center"))
+aCircleRadius = aSketchCircle.real("circle_radius")
anCircleCentr.setValue(0, 0)
aCircleRadius.setValue(10)
aSession.finishOperation()
norm.setValue(0, 0, 1)
# Create circle
aSketchCircle = aCircleSketchFeature.addFeature("SketchCircle")
-anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("CircleCenter"))
-aCircleRadius = aSketchCircle.real("CircleRadius")
+anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("circle_center"))
+aCircleRadius = aSketchCircle.real("circle_radius")
anCircleCentr.setValue(-10, 0)
aCircleRadius.setValue(50)
aSession.finishOperation()
norm.setValue(0, 0, 1)
# Create circle
aSketchCircle = aCircleSketchFeature.addFeature("SketchCircle")
-anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("CircleCenter"))
-aCircleRadius = aSketchCircle.real("CircleRadius")
+anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("circle_center"))
+aCircleRadius = aSketchCircle.real("circle_radius")
anCircleCentr.setValue(10, 0)
aCircleRadius.setValue(50)
aSession.finishOperation()
norm = geomDataAPI_Dir(aSketchFeature.attribute("Norm"))
norm.setValue(0, 0, 1)
aSketchCircle = aSketchFeature.addFeature("SketchCircle")
- anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("CircleCenter"))
- aCircleRadius = aSketchCircle.real("CircleRadius")
+ anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("circle_center"))
+ aCircleRadius = aSketchCircle.real("circle_radius")
anCircleCentr.setValue(0.5 + step * (0.5 + i), 0.5 + step * (0.5 + j))
aCircleRadius.setValue(radius)
aSketchFeatures.append(aSketchFeature)
norm.setValue(0, 0, 1)
# Create circle
aSketchCircle = aCircleSketchFeature.addFeature("SketchCircle")
-anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("CircleCenter"))
-aCircleRadius = aSketchCircle.real("CircleRadius")
+anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("circle_center"))
+aCircleRadius = aSketchCircle.real("circle_radius")
anCircleCentr.setValue(0, 0)
aCircleRadius.setValue(50)
aSession.finishOperation()
# Create circle
aSketchCircleFeature = aSketchFeature.addFeature("SketchCircle")
-anCircleCentr = geomDataAPI_Point2D(aSketchCircleFeature.attribute("CircleCenter"))
-aCircleRadius = aSketchCircleFeature.real("CircleRadius")
+anCircleCentr = geomDataAPI_Point2D(aSketchCircleFeature.attribute("circle_center"))
+aCircleRadius = aSketchCircleFeature.real("circle_radius")
anCircleCentr.setValue(0, 0)
aCircleRadius.setValue(10)
aSession.finishOperation()
# Create arc
aSketchArcFeature = aSketchFeature.addFeature("SketchArc")
-aSketchArcFeature.string("ArcType").setValue("CenterStartEnd")
-aSketchArcCenterPoint = geomDataAPI_Point2D(aSketchArcFeature.attribute("ArcCenter"))
-aSketchArcStartPoint = geomDataAPI_Point2D(aSketchArcFeature.attribute("ArcStartPoint"))
-aSketchArcEndPoint = geomDataAPI_Point2D(aSketchArcFeature.attribute("ArcEndPoint"))
+aSketchArcCenterPoint = geomDataAPI_Point2D(aSketchArcFeature.attribute("center_point"))
+aSketchArcStartPoint = geomDataAPI_Point2D(aSketchArcFeature.attribute("start_point"))
+aSketchArcEndPoint = geomDataAPI_Point2D(aSketchArcFeature.attribute("end_point"))
aSketchArcCenterPoint.setValue(100, 200)
aSketchArcStartPoint.setValue(200, 200)
aSketchArcEndPoint.setValue(0, 200)
# Create circle
aSketchCircleFeature = aSketchFeature.addFeature("SketchCircle")
-anCircleCentr = geomDataAPI_Point2D(aSketchCircleFeature.attribute("CircleCenter"))
-aCircleRadius = aSketchCircleFeature.real("CircleRadius")
+anCircleCentr = geomDataAPI_Point2D(aSketchCircleFeature.attribute("circle_center"))
+aCircleRadius = aSketchCircleFeature.real("circle_radius")
anCircleCentr.setValue(0, 0)
aCircleRadius.setValue(20)
aSession.finishOperation()
# Create circles
aSketchCircle = aSketchFeature.addFeature("SketchCircle")
-anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("CircleCenter"))
-aCircleRadius = aSketchCircle.real("CircleRadius")
+anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("circle_center"))
+aCircleRadius = aSketchCircle.real("circle_radius")
anCircleCentr.setValue(-25, 0)
aCircleRadius.setValue(50)
aSketchCircle = aSketchFeature.addFeature("SketchCircle")
-anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("CircleCenter"))
-aCircleRadius = aSketchCircle.real("CircleRadius")
+anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("circle_center"))
+aCircleRadius = aSketchCircle.real("circle_radius")
anCircleCentr.setValue(25, 0)
aCircleRadius.setValue(50)
aSession.finishOperation()
# Create circle
aSketchCircle = aCircleSketchFeature.addFeature("SketchCircle")
-anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("CircleCenter"))
-aCircleRadius = aSketchCircle.real("CircleRadius")
+anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("circle_center"))
+aCircleRadius = aSketchCircle.real("circle_radius")
anCircleCentr.setValue(0., 0.)
aCircleRadius.setValue(30.)
aSession.finishOperation()
norm.setValue(0, 0, 1)
# Create circle
aSketchCircle = aCircleSketchFeature.addFeature("SketchCircle")
-anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("CircleCenter"))
-aCircleRadius = aSketchCircle.real("CircleRadius")
+anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("circle_center"))
+aCircleRadius = aSketchCircle.real("circle_radius")
anCircleCentr.setValue(0, 0)
aCircleRadius.setValue(20)
aSession.finishOperation()
aCircleSketchFeature.selection("External").selectSubShape("face", "Extrusion_1/To_Face_1")
aSession.startOperation()
aSketchCircle = aCircleSketchFeature.addFeature("SketchCircle")
-anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("CircleCenter"))
-aCircleRadius = aSketchCircle.real("CircleRadius")
+anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("circle_center"))
+aCircleRadius = aSketchCircle.real("circle_radius")
anCircleCentr.setValue(0, 0)
aCircleRadius.setValue(10)
aSession.finishOperation()
norm.setValue(0, 0, 1)
# Create circle
aSketchCircle = aCircleSketchFeature.addFeature("SketchCircle")
-anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("CircleCenter"))
-aCircleRadius = aSketchCircle.real("CircleRadius")
+anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("circle_center"))
+aCircleRadius = aSketchCircle.real("circle_radius")
anCircleCentr.setValue(0, 0)
aCircleRadius.setValue(20)
aSession.finishOperation()
aCircleSketchFeature.selection("External").selectSubShape("face", "Extrusion_1/To_Face_1")
aSession.startOperation()
aSketchCircle = aCircleSketchFeature.addFeature("SketchCircle")
-anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("CircleCenter"))
-aCircleRadius = aSketchCircle.real("CircleRadius")
+anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("circle_center"))
+aCircleRadius = aSketchCircle.real("circle_radius")
anCircleCentr.setValue(0, 0)
aCircleRadius.setValue(10)
aSession.finishOperation()
norm.setValue(0, 0, 1)
# Create circle
aSketchCircle = aCircleSketchFeature.addFeature("SketchCircle")
-anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("CircleCenter"))
-aCircleRadius = aSketchCircle.real("CircleRadius")
+anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("circle_center"))
+aCircleRadius = aSketchCircle.real("circle_radius")
anCircleCentr.setValue(50, 50)
aCircleRadius.setValue(20)
aSession.finishOperation()
norm = geomDataAPI_Dir(aSketchFeature.attribute("Norm"))
norm.setValue(0, 0, 1)
aSketchCircle = aSketchFeature.addFeature("SketchCircle")
- anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("CircleCenter"))
- aCircleRadius = aSketchCircle.real("CircleRadius")
+ anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("circle_center"))
+ aCircleRadius = aSketchCircle.real("circle_radius")
anCircleCentr.setValue(0.5 + step * (0.5 + i), 0.5 + step * (0.5 + j))
aCircleRadius.setValue(radius)
aSketchFeatures.append(aSketchFeature)
norm.setValue(0, 0, 1)
# Create circle
aSketchCircle = aCircleSketchFeature.addFeature("SketchCircle")
-anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("CircleCenter"))
-aCircleRadius = aSketchCircle.real("CircleRadius")
+anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("circle_center"))
+aCircleRadius = aSketchCircle.real("circle_radius")
anCircleCentr.setValue(50, 50)
aCircleRadius.setValue(20)
aSession.finishOperation()
# Create circles
aSketchCircle = aSketchFeature.addFeature("SketchCircle")
-anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("CircleCenter"))
-aCircleRadius = aSketchCircle.real("CircleRadius")
+anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("circle_center"))
+aCircleRadius = aSketchCircle.real("circle_radius")
anCircleCentr.setValue(-25, 0)
aCircleRadius.setValue(50)
aSketchCircle = aSketchFeature.addFeature("SketchCircle")
-anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("CircleCenter"))
-aCircleRadius = aSketchCircle.real("CircleRadius")
+anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("circle_center"))
+aCircleRadius = aSketchCircle.real("circle_radius")
anCircleCentr.setValue(25, 0)
aCircleRadius.setValue(50)
aSession.finishOperation()
%include "GeomAPI_XYZ.h"
%include "GeomAPI_Trsf.h"
%include "GeomAPI_Wire.h"
-
-%include "std_list.i"
-%include "std_set.i"
-
-%template(PointList) std::list<std::shared_ptr<GeomAPI_Pnt> >;
-%template(PointSet) std::set<std::shared_ptr<GeomAPI_Pnt> >;
// Author: Artem ZHIDKOV
#include <GeomAPI_Circ2d.h>
-#include <GeomAPI_Ax3.h>
#include <GeomAPI_Pnt2d.h>
#include <GeomAPI_Dir2d.h>
-#include <GeomAPI_Shape.h>
-#include <BRep_Tool.hxx>
-#include <gp_Dir2d.hxx>
#include <gp_Circ2d.hxx>
-#include <gp_Lin2d.hxx>
#include <gp_Pnt2d.hxx>
-#include <gp_Ax2d.hxx>
-#include <GccAna_Circ2d3Tan.hxx>
-#include <GccAna_Circ2dTanCen.hxx>
-#include <GccEnt.hxx>
-#include <GccEnt_QualifiedCirc.hxx>
-#include <GccEnt_QualifiedLin.hxx>
#include <GeomLib_Tool.hxx>
#include <Geom2d_Circle.hxx>
-#include <Geom2dAPI_ProjectPointOnCurve.hxx>
-#include <Geom_Plane.hxx>
-#include <IntAna2d_AnaIntersection.hxx>
#include <Precision.hxx>
-#include <TopoDS.hxx>
-#include <TopoDS_Edge.hxx>
-
-#include <vector>
#define MY_CIRC2D implPtr<gp_Circ2d>()
-typedef std::shared_ptr<Geom2dAdaptor_Curve> CurveAdaptorPtr;
-
-class CircleBuilder
-{
-public:
- CircleBuilder(const std::shared_ptr<GeomAPI_Ax3>& theBasePlane)
- : myPlane(new Geom_Plane(theBasePlane->impl<gp_Ax3>()))
- {}
-
- void addCenter(const std::shared_ptr<GeomAPI_Pnt2d>& theCenter)
- { myCenter = theCenter; }
-
- void addPassingEntity(const std::shared_ptr<GeomAPI_Interface>& theEntity)
- {
- std::shared_ptr<GeomAPI_Pnt2d> aPoint = std::dynamic_pointer_cast<GeomAPI_Pnt2d>(theEntity);
- if (aPoint)
- addPassingPoint(aPoint);
- else {
- std::shared_ptr<GeomAPI_Shape> aShape = std::dynamic_pointer_cast<GeomAPI_Shape>(theEntity);
- if (aShape)
- addTangentCurve(aShape);
- }
- }
-
- void addTangentCurve(const std::shared_ptr<GeomAPI_Shape>& theEdge)
- {
- if (!theEdge->isEdge())
- return;
-
- const TopoDS_Edge& anEdge = TopoDS::Edge(theEdge->impl<TopoDS_Shape>());
-
- double aFirst, aLast;
- TopLoc_Location aLoc;
- Handle(Geom2d_Curve) aCurve = BRep_Tool::CurveOnSurface(anEdge, myPlane, aLoc, aFirst, aLast);
- CurveAdaptorPtr aCurveAdaptor(new Geom2dAdaptor_Curve(aCurve, aFirst, aLast));
-
- myTangentShapes.push_back(aCurveAdaptor);
- }
-
- void addPassingPoint(const std::shared_ptr<GeomAPI_Pnt2d>& thePoint)
- {
- myPassingPoints.push_back(thePoint->impl<gp_Pnt2d>());
- }
-
- gp_Circ2d* circle()
- {
- gp_Circ2d* aResult = 0;
- if (myCenter) {
- if (myPassingPoints.size() == 1)
- aResult = circleByCenterAndPassingPoint();
- else if (myTangentShapes.size() == 1)
- aResult = circleByCenterAndTangent();
- } else {
- switch (myPassingPoints.size()) {
- case 0:
- aResult = circleByThreeTangentCurves();
- break;
- case 1:
- aResult = circleByPointAndTwoTangentCurves();
- break;
- case 2:
- aResult = circleByTwoPointsAndTangentCurve();
- break;
- case 3:
- aResult = circleByThreePassingPoints();
- break;
- default:
- break;
- }
- }
- return aResult;
- }
-
-private:
- gp_Circ2d* circleByCenterAndPassingPoint()
- {
- const gp_Pnt2d& aCenter = myCenter->impl<gp_Pnt2d>();
- GccAna_Circ2dTanCen aBuilder(myPassingPoints[0], aCenter);
- if (aBuilder.NbSolutions() > 0)
- return new gp_Circ2d(aBuilder.ThisSolution(1));
- return 0;
- }
-
- gp_Circ2d* circleByCenterAndTangent()
- {
- const gp_Pnt2d& aCenter = myCenter->impl<gp_Pnt2d>();
- CurveAdaptorPtr aCurve = myTangentShapes[0];
-
- std::shared_ptr<GccAna_Circ2dTanCen> aCircleBuilder;
- if (aCurve->GetType() == GeomAbs_Line) {
- aCircleBuilder = std::shared_ptr<GccAna_Circ2dTanCen>(
- new GccAna_Circ2dTanCen(aCurve->Line(), aCenter));
- } else if (aCurve->GetType() == GeomAbs_Circle) {
- aCircleBuilder = std::shared_ptr<GccAna_Circ2dTanCen>(new GccAna_Circ2dTanCen(
- GccEnt::Unqualified(aCurve->Circle()), aCenter, Precision::Confusion()));
- }
-
- return getProperCircle(aCircleBuilder);
- }
-
- gp_Circ2d* getProperCircle(const std::shared_ptr<GccAna_Circ2dTanCen>& theBuilder) const
- {
- if (!theBuilder)
- return 0;
-
- CurveAdaptorPtr aCurve = myTangentShapes[0];
-
- gp_Circ2d* aResult = 0;
- int aNbSol = theBuilder->NbSolutions();
- double aParSol, aPonTgCurve;
- gp_Pnt2d aTgPnt;
- for (int i = 1; i <= aNbSol && aCurve; ++i) {
- theBuilder->Tangency1(i, aParSol, aPonTgCurve, aTgPnt);
- if (aPonTgCurve >= aCurve->FirstParameter() && aPonTgCurve <= aCurve->LastParameter()) {
- aResult = new gp_Circ2d(theBuilder->ThisSolution(i));
- break;
- }
- }
- // unable to build circle passing through the tangent curve,
- // so get a circle passing any tangent point
- if (!aResult && aNbSol > 0)
- aResult = new gp_Circ2d(theBuilder->ThisSolution(1));
- return aResult;
- }
-
-
- gp_Circ2d* circleByThreeTangentCurves()
- {
- std::shared_ptr<GccEnt_QualifiedCirc> aTgCirc[3];
- std::shared_ptr<GccEnt_QualifiedLin> aTgLine[3];
- int aNbTgCirc = 0;
- int aNbTgLine = 0;
-
- std::vector<CurveAdaptorPtr>::iterator anIt = myTangentShapes.begin();
- for (; anIt != myTangentShapes.end(); ++anIt) {
- switch ((*anIt)->GetType()) {
- case GeomAbs_Line:
- aTgLine[aNbTgLine++] = std::shared_ptr<GccEnt_QualifiedLin>(
- new GccEnt_QualifiedLin((*anIt)->Line(), GccEnt_unqualified));
- break;
- case GeomAbs_Circle:
- aTgCirc[aNbTgCirc++] = std::shared_ptr<GccEnt_QualifiedCirc>(
- new GccEnt_QualifiedCirc((*anIt)->Circle(), GccEnt_unqualified));
- break;
- default:
- break;
- }
- }
- if (aNbTgCirc + aNbTgLine != 3)
- return 0;
-
- std::shared_ptr<GccAna_Circ2d3Tan> aCircleBuilder;
- switch (aNbTgLine) {
- case 0:
- aCircleBuilder = std::shared_ptr<GccAna_Circ2d3Tan>(new GccAna_Circ2d3Tan(
- *aTgCirc[0], *aTgCirc[1], *aTgCirc[2], Precision::Confusion()));
- break;
- case 1:
- aCircleBuilder = std::shared_ptr<GccAna_Circ2d3Tan>(new GccAna_Circ2d3Tan(
- *aTgCirc[0], *aTgCirc[1], *aTgLine[0], Precision::Confusion()));
- break;
- case 2:
- aCircleBuilder = std::shared_ptr<GccAna_Circ2d3Tan>(new GccAna_Circ2d3Tan(
- *aTgCirc[0], *aTgLine[0], *aTgLine[1], Precision::Confusion()));
- break;
- case 3:
- aCircleBuilder = std::shared_ptr<GccAna_Circ2d3Tan>(new GccAna_Circ2d3Tan(
- *aTgLine[0], *aTgLine[1], *aTgLine[0], Precision::Confusion()));
- break;
- default:
- break;
- }
-
- return getProperCircle(aCircleBuilder);
- }
-
- gp_Circ2d* circleByPointAndTwoTangentCurves()
- {
- const gp_Pnt2d& aPoint = myPassingPoints[0];
- CurveAdaptorPtr aCurve1 = myTangentShapes[0];
- CurveAdaptorPtr aCurve2 = myTangentShapes[1];
- if (!aCurve1 || !aCurve2)
- return 0;
-
- std::shared_ptr<GccAna_Circ2d3Tan> aCircleBuilder;
- if (aCurve1->GetType() == GeomAbs_Line) {
- if (aCurve2->GetType() == GeomAbs_Line) {
- aCircleBuilder = std::shared_ptr<GccAna_Circ2d3Tan>(
- new GccAna_Circ2d3Tan(GccEnt::Unqualified(aCurve1->Line()),
- GccEnt::Unqualified(aCurve2->Line()),
- aPoint, Precision::Confusion()));
- } else if (aCurve2->GetType() == GeomAbs_Circle) {
- aCircleBuilder = std::shared_ptr<GccAna_Circ2d3Tan>(
- new GccAna_Circ2d3Tan(GccEnt::Unqualified(aCurve2->Circle()),
- GccEnt::Unqualified(aCurve1->Line()),
- aPoint, Precision::Confusion()));
- }
- } else if (aCurve1->GetType() == GeomAbs_Circle) {
- if (aCurve2->GetType() == GeomAbs_Line) {
- aCircleBuilder = std::shared_ptr<GccAna_Circ2d3Tan>(
- new GccAna_Circ2d3Tan(GccEnt::Unqualified(aCurve1->Circle()),
- GccEnt::Unqualified(aCurve2->Line()),
- aPoint, Precision::Confusion()));
- } else if (aCurve2->GetType() == GeomAbs_Circle) {
- aCircleBuilder = std::shared_ptr<GccAna_Circ2d3Tan>(
- new GccAna_Circ2d3Tan(GccEnt::Unqualified(aCurve2->Circle()),
- GccEnt::Unqualified(aCurve1->Circle()),
- aPoint, Precision::Confusion()));
- }
- }
-
- return getProperCircle(aCircleBuilder);
- }
-
- gp_Circ2d* circleByTwoPointsAndTangentCurve()
- {
- const gp_Pnt2d& aPoint1 = myPassingPoints[0];
- const gp_Pnt2d& aPoint2 = myPassingPoints[1];
- CurveAdaptorPtr aCurve = myTangentShapes[0];
- if (!aCurve)
- return 0;
-
- std::shared_ptr<GccAna_Circ2d3Tan> aCircleBuilder;
- if (aCurve->GetType() == GeomAbs_Line) {
- aCircleBuilder = std::shared_ptr<GccAna_Circ2d3Tan>(new GccAna_Circ2d3Tan(
- GccEnt::Unqualified(aCurve->Line()), aPoint1, aPoint2, Precision::Confusion()));
- } else if (aCurve->GetType() == GeomAbs_Circle) {
- aCircleBuilder = std::shared_ptr<GccAna_Circ2d3Tan>(new GccAna_Circ2d3Tan(
- GccEnt::Unqualified(aCurve->Circle()), aPoint1, aPoint2, Precision::Confusion()));
- }
-
- return getProperCircle(aCircleBuilder);
- }
-
- gp_Circ2d* circleByThreePassingPoints()
- {
- GccAna_Circ2d3Tan aCircleBuilder(myPassingPoints[0],
- myPassingPoints[1],
- myPassingPoints[2],
- Precision::Confusion());
- if (aCircleBuilder.NbSolutions() > 0)
- return new gp_Circ2d(aCircleBuilder.ThisSolution(1));
- return 0;
- }
-
-
- gp_Circ2d* getProperCircle(const std::shared_ptr<GccAna_Circ2d3Tan>& theBuilder) const
- {
- if (!theBuilder)
- return 0;
-
- gp_Circ2d* aResult = 0;
- int aNbSol = theBuilder->NbSolutions();
- double aParSol, aPonTgCurve;
- gp_Pnt2d aTgPnt;
- for (int i = 1; i <= aNbSol; ++i) {
- bool isApplicable = false;
- if (myTangentShapes.size() >= 1) {
- theBuilder->Tangency1(i, aParSol, aPonTgCurve, aTgPnt);
- isApplicable = aPonTgCurve >= myTangentShapes[0]->FirstParameter() &&
- aPonTgCurve <= myTangentShapes[0]->LastParameter();
- }
- if (myTangentShapes.size() >= 2 && isApplicable) {
- theBuilder->Tangency2(i, aParSol, aPonTgCurve, aTgPnt);
- isApplicable = aPonTgCurve >= myTangentShapes[1]->FirstParameter() &&
- aPonTgCurve <= myTangentShapes[1]->LastParameter();
- }
- if (myTangentShapes.size() >= 3 && isApplicable) {
- theBuilder->Tangency3(i, aParSol, aPonTgCurve, aTgPnt);
- isApplicable = aPonTgCurve >= myTangentShapes[2]->FirstParameter() &&
- aPonTgCurve <= myTangentShapes[2]->LastParameter();
- }
-
- if (isApplicable) {
- aResult = new gp_Circ2d(theBuilder->ThisSolution(i));
- break;
- }
- }
- // unable to build circle passing through the tangent curve => get any tangent point
- if (!aResult && aNbSol > 0)
- aResult = new gp_Circ2d(theBuilder->ThisSolution(1));
- return aResult;
- }
-
-private:
- Handle(Geom_Plane) myPlane;
- std::shared_ptr<GeomAPI_Pnt2d> myCenter;
- std::vector<gp_Pnt2d> myPassingPoints;
- std::vector<CurveAdaptorPtr> myTangentShapes;
-};
-
-typedef std::shared_ptr<CircleBuilder> CircleBuilderPtr;
-
static gp_Circ2d* newCirc2d(const double theCenterX, const double theCenterY, const gp_Dir2d theDir,
const double theRadius)
return newCirc2d(theCenterX, theCenterY, aDir, aRadius);
}
-static gp_Circ2d* newCirc2d(const std::shared_ptr<GeomAPI_Pnt2d>& theFirstPoint,
- const std::shared_ptr<GeomAPI_Pnt2d>& theSecondPoint,
- const std::shared_ptr<GeomAPI_Pnt2d>& theThirdPoint)
-{
- gp_XY aFirstPnt(theFirstPoint->x(), theFirstPoint->y());
- gp_XY aSecondPnt(theSecondPoint->x(), theSecondPoint->y());
- gp_XY aThirdPnt(theThirdPoint->x(), theThirdPoint->y());
-
- gp_XY aVec12 = aSecondPnt - aFirstPnt;
- gp_XY aVec23 = aThirdPnt - aSecondPnt;
- gp_XY aVec31 = aFirstPnt - aThirdPnt;
-
- // coefficients to calculate center
- double aCoeff1, aCoeff2, aCoeff3;
-
- // square of parallelogram
- double aSquare2 = aVec12.Crossed(aVec23);
- aSquare2 *= aSquare2 * 2.0;
- if (aSquare2 < 1.e-20) {
- // if two points are equal, build a circle on two different points as on diameter
- double aSqLen12 = aVec12.SquareModulus();
- double aSqLen23 = aVec23.SquareModulus();
- double aSqLen31 = aVec31.SquareModulus();
- if (aSqLen12 < Precision::SquareConfusion() &&
- aSqLen23 < Precision::SquareConfusion() &&
- aSqLen31 < Precision::SquareConfusion())
- return NULL;
- aCoeff1 = aCoeff2 = aCoeff3 = 1.0 / 3.0;
- }
- else {
- aCoeff1 = aVec23.Dot(aVec23) / aSquare2 * aVec12.Dot(aVec31.Reversed());
- aCoeff2 = aVec31.Dot(aVec31) / aSquare2 * aVec23.Dot(aVec12.Reversed());
- aCoeff3 = aVec12.Dot(aVec12) / aSquare2 * aVec31.Dot(aVec23.Reversed());
- }
- // center
- gp_XY aCenter = aFirstPnt * aCoeff1 + aSecondPnt * aCoeff2 + aThirdPnt * aCoeff3;
- // radius
- double aRadius = (aFirstPnt - aCenter).Modulus();
-
- gp_Dir2d aDir(aFirstPnt - aCenter);
- return newCirc2d(aCenter.X(), aCenter.Y(), aDir, aRadius);
-}
-
GeomAPI_Circ2d::GeomAPI_Circ2d(const std::shared_ptr<GeomAPI_Pnt2d>& theCenter,
{
}
-GeomAPI_Circ2d::GeomAPI_Circ2d(const std::shared_ptr<GeomAPI_Pnt2d>& theFirstPoint,
- const std::shared_ptr<GeomAPI_Pnt2d>& theSecondPoint,
- const std::shared_ptr<GeomAPI_Pnt2d>& theThirdPoint)
- : GeomAPI_Interface(newCirc2d(theFirstPoint, theSecondPoint, theThirdPoint))
-{
-}
-
-GeomAPI_Circ2d::GeomAPI_Circ2d(const std::shared_ptr<GeomAPI_Pnt2d>& theCenter,
- const std::shared_ptr<GeomAPI_Shape>& theTangent,
- const std::shared_ptr<GeomAPI_Ax3>& thePlane)
-{
- CircleBuilderPtr aBuilder(new CircleBuilder(thePlane));
- aBuilder->addCenter(theCenter);
- aBuilder->addTangentCurve(theTangent);
- setImpl(aBuilder->circle());
-}
-
-GeomAPI_Circ2d::GeomAPI_Circ2d(const std::shared_ptr<GeomAPI_Interface>& theEntity1,
- const std::shared_ptr<GeomAPI_Interface>& theEntity2,
- const std::shared_ptr<GeomAPI_Interface>& theEntity3,
- const std::shared_ptr<GeomAPI_Ax3>& thePlane)
-{
- CircleBuilderPtr aBuilder(new CircleBuilder(thePlane));
- aBuilder->addPassingEntity(theEntity1);
- aBuilder->addPassingEntity(theEntity2);
- aBuilder->addPassingEntity(theEntity3);
- setImpl(aBuilder->circle());
-}
-
-
const std::shared_ptr<GeomAPI_Pnt2d> GeomAPI_Circ2d::project(
const std::shared_ptr<GeomAPI_Pnt2d>& thePoint) const
{
GeomAPI_Circ2d(const std::shared_ptr<GeomAPI_Pnt2d>& theCenter,
const std::shared_ptr<GeomAPI_Dir2d>& theDir, double theRadius);
- /// Creation of circle defined by three points lying on it
- GEOMAPI_EXPORT
- GeomAPI_Circ2d(const std::shared_ptr<GeomAPI_Pnt2d>& theFirstPoint,
- const std::shared_ptr<GeomAPI_Pnt2d>& theSecondPoint,
- const std::shared_ptr<GeomAPI_Pnt2d>& theThirdPoint);
-
- /// Creation of a circle defined by center and a tangent curve on the given plane
- GEOMAPI_EXPORT
- GeomAPI_Circ2d(const std::shared_ptr<GeomAPI_Pnt2d>& theCenter,
- const std::shared_ptr<GeomAPI_Shape>& theTangent,
- const std::shared_ptr<GeomAPI_Ax3>& thePlane);
-
- /// Creation of a circle passing through or tangent to given entities.
- /// Supported items are GeomAPI_Pnt2d or GeomAPI_Shape
- GEOMAPI_EXPORT
- GeomAPI_Circ2d(const std::shared_ptr<GeomAPI_Interface>& theEntity1,
- const std::shared_ptr<GeomAPI_Interface>& theEntity2,
- const std::shared_ptr<GeomAPI_Interface>& theEntity3,
- const std::shared_ptr<GeomAPI_Ax3>& thePlane);
-
/// Return center of the circle
GEOMAPI_EXPORT
const std::shared_ptr<GeomAPI_Pnt2d> center() const;
if (aResult.ShapeType() == TopAbs_COMPOUND) {
NCollection_List<TopoDS_Shape> aSubs;
addSimpleToList(aResult, aSubs);
- if (aSubs.Size() == 1)
+ if(aSubs.Size() == 1) {
aResult = aSubs.First();
+ } else if(aSubs.Size() == 0) {
+ return GeomShapePtr();
+ }
}
GeomShapePtr aResShape(new GeomAPI_Shape);
GeomAlgoAPI_ConeSegment.h
GeomAlgoAPI_Symmetry.h
GeomAlgoAPI_Scale.h
+ GeomAlgoAPI_Circ2dBuilder.h
)
SET(PROJECT_SOURCES
GeomAlgoAPI_ConeSegment.cpp
GeomAlgoAPI_Symmetry.cpp
GeomAlgoAPI_Scale.cpp
+ GeomAlgoAPI_Circ2dBuilder.cpp
)
SET(PROJECT_LIBRARIES
%module GeomAlgoAPI
%{
#include "GeomAlgoAPI_swig.h"
-
- // fix for SWIG v2.0.4
- #define SWIGPY_SLICE_ARG(obj) ((PySliceObject*)(obj))
%}
// import other modules
--- /dev/null
+// Copyright (C) 2017-20xx CEA/DEN, EDF R&D
+
+// File: GeomAlgoAPI_Circ2dBuilder.cpp
+// Created: 3 April 2017
+// Author: Artem ZHIDKOV
+
+#include <GeomAlgoAPI_Circ2dBuilder.h>
+#include <GeomAPI_Ax3.h>
+#include <GeomAPI_Circ2d.h>
+#include <GeomAPI_Pnt2d.h>
+#include <GeomAPI_Dir2d.h>
+#include <GeomAPI_Shape.h>
+
+#include <BRep_Tool.hxx>
+#include <ElCLib.hxx>
+#include <GccAna_Circ2d2TanRad.hxx>
+#include <GccAna_Circ2d3Tan.hxx>
+#include <GccAna_Circ2dTanCen.hxx>
+#include <GccEnt.hxx>
+#include <GccEnt_QualifiedCirc.hxx>
+#include <GccEnt_QualifiedLin.hxx>
+#include <Geom2dAdaptor_Curve.hxx>
+#include <Geom_Plane.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Edge.hxx>
+
+#include <cmath>
+
+typedef std::shared_ptr<gp_Circ2d> Circ2dPtr;
+typedef std::shared_ptr<Geom2dAdaptor_Curve> CurveAdaptorPtr;
+typedef std::vector< std::shared_ptr<GccEnt_QualifiedCirc> > VectorOfGccCirc;
+typedef std::vector< std::shared_ptr<GccEnt_QualifiedLin> > VectorOfGccLine;
+
+
+// Provide different mechanisms to create circle:
+// * by passing points
+// * by tangent edges
+// * with specified radius
+// * etc.
+class CircleBuilder
+{
+public:
+ CircleBuilder(const std::shared_ptr<GeomAPI_Ax3>& theBasePlane)
+ : myPlane(new Geom_Plane(theBasePlane->impl<gp_Ax3>())),
+ myRadius(0.0)
+ {}
+
+ void setRadius(const double theRadius)
+ { myRadius = theRadius; }
+
+ void setCenter(const std::shared_ptr<GeomAPI_Pnt2d>& theCenter)
+ { myCenter = theCenter; }
+
+ void setTangentCurves(const std::vector< std::shared_ptr<GeomAPI_Shape> >& theEdges)
+ {
+ std::vector< std::shared_ptr<GeomAPI_Shape> >::const_iterator anEdgeIt;
+ for (anEdgeIt = theEdges.begin(); anEdgeIt != theEdges.end(); ++anEdgeIt) {
+ const TopoDS_Edge& anEdge = TopoDS::Edge((*anEdgeIt)->impl<TopoDS_Shape>());
+
+ double aFirst, aLast;
+ TopLoc_Location aLoc;
+ Handle(Geom2d_Curve) aCurve = BRep_Tool::CurveOnSurface(anEdge, myPlane, aLoc, aFirst, aLast);
+ CurveAdaptorPtr aCurveAdaptor(new Geom2dAdaptor_Curve(aCurve, aFirst, aLast));
+
+ // sort curves (circles should become first)
+ if (aCurveAdaptor->GetType() == GeomAbs_Circle)
+ myTangentShapes.insert(myTangentShapes.begin(), aCurveAdaptor);
+ else
+ myTangentShapes.push_back(aCurveAdaptor);
+ }
+ }
+
+ void setPassingPoints(const std::vector< std::shared_ptr<GeomAPI_Pnt2d> >& thePoints)
+ {
+ std::vector< std::shared_ptr<GeomAPI_Pnt2d> >::const_iterator aPIt;
+ for (aPIt = thePoints.begin(); aPIt != thePoints.end(); ++aPIt)
+ myPassingPoints.push_back((*aPIt)->impl<gp_Pnt2d>());
+ }
+
+ void setClosestPoint(const std::shared_ptr<GeomAPI_Pnt2d>& thePoint)
+ { myClosestPoint = thePoint; }
+
+
+ Circ2dPtr circle()
+ {
+ Circ2dPtr aResult;
+ if (myCenter) {
+ if (myPassingPoints.size() == 1)
+ aResult = circleByCenterAndPassingPoint();
+ else if (myTangentShapes.size() == 1)
+ aResult = circleByCenterAndTangent();
+ else if (myRadius > 0.0)
+ aResult = circleByCenterAndRadius();
+ } else if (myRadius > 0.0) {
+ if (myTangentShapes.size() == 2)
+ aResult = circleByRadiusAndTwoTangentCurves();
+ } else {
+ switch (myPassingPoints.size()) {
+ case 0:
+ aResult = circleByThreeTangentCurves();
+ break;
+ case 1:
+ aResult = circleByPointAndTwoTangentCurves();
+ break;
+ case 2:
+ aResult = circleByTwoPointsAndTangentCurve();
+ break;
+ case 3:
+ aResult = circleByThreePassingPoints();
+ break;
+ default:
+ break;
+ }
+ }
+ return aResult;
+ }
+
+private:
+ Circ2dPtr circleByCenterAndRadius()
+ {
+ const gp_Pnt2d& aCenter = myCenter->impl<gp_Pnt2d>();
+ return Circ2dPtr(new gp_Circ2d(gp_Ax2d(aCenter, gp::DX2d()), myRadius));
+ }
+
+ Circ2dPtr circleByCenterAndPassingPoint()
+ {
+ const gp_Pnt2d& aCenter = myCenter->impl<gp_Pnt2d>();
+ if (aCenter.SquareDistance(myPassingPoints[0]) > Precision::SquareConfusion()) {
+ GccAna_Circ2dTanCen aBuilder(myPassingPoints[0], aCenter);
+ if (aBuilder.NbSolutions() > 0)
+ return Circ2dPtr(new gp_Circ2d(aBuilder.ThisSolution(1)));
+ }
+ return Circ2dPtr();
+ }
+
+ Circ2dPtr circleByCenterAndTangent()
+ {
+ const gp_Pnt2d& aCenter = myCenter->impl<gp_Pnt2d>();
+ CurveAdaptorPtr aCurve = myTangentShapes[0];
+
+ std::shared_ptr<GccAna_Circ2dTanCen> aCircleBuilder;
+ if (aCurve->GetType() == GeomAbs_Line) {
+ aCircleBuilder = std::shared_ptr<GccAna_Circ2dTanCen>(
+ new GccAna_Circ2dTanCen(aCurve->Line(), aCenter));
+ } else if (aCurve->GetType() == GeomAbs_Circle) {
+ aCircleBuilder = std::shared_ptr<GccAna_Circ2dTanCen>(new GccAna_Circ2dTanCen(
+ GccEnt::Unqualified(aCurve->Circle()), aCenter, Precision::Confusion()));
+ }
+
+ return getProperCircle(aCircleBuilder);
+ }
+
+ Circ2dPtr getProperCircle(const std::shared_ptr<GccAna_Circ2dTanCen>& theBuilder) const
+ {
+ if (!theBuilder)
+ return Circ2dPtr();
+
+ CurveAdaptorPtr aCurve = myTangentShapes[0];
+
+ int aNbSol = theBuilder->NbSolutions();
+ if (aNbSol == 0)
+ return Circ2dPtr();
+
+ int anAppropriateSolution = 1;
+ double aMinDist = Precision::Infinite();
+
+ double aParSol, aPonTgCurve;
+ gp_Pnt2d aTgPnt;
+ for (int i = 1; i <= aNbSol && aCurve; ++i) {
+ theBuilder->Tangency1(i, aParSol, aPonTgCurve, aTgPnt);
+ if (isParamOnCurve(aPonTgCurve, aCurve)) {
+ double aDist = distanceToClosestPoint(theBuilder->ThisSolution(i));
+ if (aDist < aMinDist) {
+ anAppropriateSolution = i;
+ aMinDist = aDist;
+ }
+ }
+ }
+
+ return Circ2dPtr(new gp_Circ2d(theBuilder->ThisSolution(anAppropriateSolution)));
+ }
+
+ double distanceToClosestPoint(const gp_Circ2d& theCirc) const
+ {
+ if (myClosestPoint) {
+ double aDist = myClosestPoint->impl<gp_Pnt2d>().Distance(theCirc.Location());
+ return fabs(aDist - theCirc.Radius());
+ }
+ return 0.0;
+ }
+
+
+ Circ2dPtr circleByThreeTangentCurves()
+ {
+ VectorOfGccCirc aTgCirc;
+ VectorOfGccLine aTgLine;
+ convertTangentCurvesToGccEnt(aTgCirc, aTgLine);
+
+ if (aTgCirc.size() + aTgLine.size() != 3)
+ return Circ2dPtr();
+
+ std::shared_ptr<GccAna_Circ2d3Tan> aCircleBuilder;
+ switch (aTgLine.size()) {
+ case 0:
+ aCircleBuilder = std::shared_ptr<GccAna_Circ2d3Tan>(new GccAna_Circ2d3Tan(
+ *aTgCirc[0], *aTgCirc[1], *aTgCirc[2], Precision::Confusion()));
+ break;
+ case 1:
+ aCircleBuilder = std::shared_ptr<GccAna_Circ2d3Tan>(new GccAna_Circ2d3Tan(
+ *aTgCirc[0], *aTgCirc[1], *aTgLine[0], Precision::Confusion()));
+ break;
+ case 2:
+ aCircleBuilder = std::shared_ptr<GccAna_Circ2d3Tan>(new GccAna_Circ2d3Tan(
+ *aTgCirc[0], *aTgLine[0], *aTgLine[1], Precision::Confusion()));
+ break;
+ case 3:
+ aCircleBuilder = std::shared_ptr<GccAna_Circ2d3Tan>(new GccAna_Circ2d3Tan(
+ *aTgLine[0], *aTgLine[1], *aTgLine[0], Precision::Confusion()));
+ break;
+ default:
+ break;
+ }
+
+ return getProperCircle(aCircleBuilder);
+ }
+
+ Circ2dPtr circleByPointAndTwoTangentCurves()
+ {
+ const gp_Pnt2d& aPoint = myPassingPoints[0];
+ CurveAdaptorPtr aCurve1 = myTangentShapes[0];
+ CurveAdaptorPtr aCurve2 = myTangentShapes[1];
+ if (!aCurve1 || !aCurve2)
+ return Circ2dPtr();
+
+ std::shared_ptr<GccAna_Circ2d3Tan> aCircleBuilder;
+ if (aCurve1->GetType() == GeomAbs_Line) {
+ if (aCurve2->GetType() == GeomAbs_Line) {
+ aCircleBuilder = std::shared_ptr<GccAna_Circ2d3Tan>(
+ new GccAna_Circ2d3Tan(GccEnt::Unqualified(aCurve1->Line()),
+ GccEnt::Unqualified(aCurve2->Line()),
+ aPoint, Precision::Confusion()));
+ } else if (aCurve2->GetType() == GeomAbs_Circle) {
+ aCircleBuilder = std::shared_ptr<GccAna_Circ2d3Tan>(
+ new GccAna_Circ2d3Tan(GccEnt::Unqualified(aCurve2->Circle()),
+ GccEnt::Unqualified(aCurve1->Line()),
+ aPoint, Precision::Confusion()));
+ }
+ } else if (aCurve1->GetType() == GeomAbs_Circle) {
+ if (aCurve2->GetType() == GeomAbs_Line) {
+ aCircleBuilder = std::shared_ptr<GccAna_Circ2d3Tan>(
+ new GccAna_Circ2d3Tan(GccEnt::Unqualified(aCurve1->Circle()),
+ GccEnt::Unqualified(aCurve2->Line()),
+ aPoint, Precision::Confusion()));
+ } else if (aCurve2->GetType() == GeomAbs_Circle) {
+ aCircleBuilder = std::shared_ptr<GccAna_Circ2d3Tan>(
+ new GccAna_Circ2d3Tan(GccEnt::Unqualified(aCurve2->Circle()),
+ GccEnt::Unqualified(aCurve1->Circle()),
+ aPoint, Precision::Confusion()));
+ }
+ }
+
+ return getProperCircle(aCircleBuilder);
+ }
+
+ Circ2dPtr circleByTwoPointsAndTangentCurve()
+ {
+ const gp_Pnt2d& aPoint1 = myPassingPoints[0];
+ const gp_Pnt2d& aPoint2 = myPassingPoints[1];
+ CurveAdaptorPtr aCurve = myTangentShapes[0];
+ if (!aCurve)
+ return Circ2dPtr();
+
+ std::shared_ptr<GccAna_Circ2d3Tan> aCircleBuilder;
+ if (aCurve->GetType() == GeomAbs_Line) {
+ aCircleBuilder = std::shared_ptr<GccAna_Circ2d3Tan>(new GccAna_Circ2d3Tan(
+ GccEnt::Unqualified(aCurve->Line()), aPoint1, aPoint2, Precision::Confusion()));
+ } else if (aCurve->GetType() == GeomAbs_Circle) {
+ aCircleBuilder = std::shared_ptr<GccAna_Circ2d3Tan>(new GccAna_Circ2d3Tan(
+ GccEnt::Unqualified(aCurve->Circle()), aPoint1, aPoint2, Precision::Confusion()));
+ }
+
+ return getProperCircle(aCircleBuilder);
+ }
+
+ Circ2dPtr circleByThreePassingPoints()
+ {
+ GccAna_Circ2d3Tan aCircleBuilder(myPassingPoints[0],
+ myPassingPoints[1],
+ myPassingPoints[2],
+ Precision::Confusion());
+ if (aCircleBuilder.NbSolutions() > 0)
+ return Circ2dPtr(new gp_Circ2d(aCircleBuilder.ThisSolution(1)));
+ return Circ2dPtr();
+ }
+
+ Circ2dPtr getProperCircle(const std::shared_ptr<GccAna_Circ2d3Tan>& theBuilder) const
+ {
+ if (!theBuilder)
+ return Circ2dPtr();
+
+ int aNbSol = theBuilder->NbSolutions();
+ if (aNbSol == 0)
+ return Circ2dPtr();
+
+ int anAppropriateSolution = 1;
+ double aMinDist = Precision::Infinite();
+
+ double aParSol, aPonTgCurve;
+ gp_Pnt2d aTgPnt;
+ for (int i = 1; i <= aNbSol; ++i) {
+ bool isApplicable = false;
+ if (myTangentShapes.size() >= 1) {
+ theBuilder->Tangency1(i, aParSol, aPonTgCurve, aTgPnt);
+ isApplicable = isParamOnCurve(aPonTgCurve, myTangentShapes[0]);
+ }
+ if (myTangentShapes.size() >= 2 && isApplicable) {
+ theBuilder->Tangency2(i, aParSol, aPonTgCurve, aTgPnt);
+ isApplicable = isParamOnCurve(aPonTgCurve, myTangentShapes[1]);
+ }
+ if (myTangentShapes.size() >= 3 && isApplicable) {
+ theBuilder->Tangency3(i, aParSol, aPonTgCurve, aTgPnt);
+ isApplicable = isParamOnCurve(aPonTgCurve, myTangentShapes[2]);
+ }
+
+ if (isApplicable) {
+ double aDist = distanceToClosestPoint(theBuilder->ThisSolution(i));
+ if (aDist < aMinDist) {
+ anAppropriateSolution = i;
+ aMinDist = aDist;
+ }
+ }
+ }
+
+ return Circ2dPtr(new gp_Circ2d(theBuilder->ThisSolution(anAppropriateSolution)));
+ }
+
+
+ Circ2dPtr circleByRadiusAndTwoTangentCurves()
+ {
+ VectorOfGccCirc aTgCirc;
+ VectorOfGccLine aTgLine;
+ convertTangentCurvesToGccEnt(aTgCirc, aTgLine);
+
+ if (aTgCirc.size() + aTgLine.size() != 2)
+ return Circ2dPtr();
+
+ std::shared_ptr<GccAna_Circ2d2TanRad> aCircleBuilder;
+ switch (aTgLine.size()) {
+ case 0:
+ aCircleBuilder = std::shared_ptr<GccAna_Circ2d2TanRad>(new GccAna_Circ2d2TanRad(
+ *aTgCirc[0], *aTgCirc[1], myRadius, Precision::Confusion()));
+ break;
+ case 1:
+ aCircleBuilder = std::shared_ptr<GccAna_Circ2d2TanRad>(new GccAna_Circ2d2TanRad(
+ *aTgCirc[0], *aTgLine[0], myRadius, Precision::Confusion()));
+ break;
+ case 2:
+ aCircleBuilder = std::shared_ptr<GccAna_Circ2d2TanRad>(new GccAna_Circ2d2TanRad(
+ *aTgLine[0], *aTgLine[1], myRadius, Precision::Confusion()));
+ break;
+ default:
+ break;
+ }
+
+ return getProperCircle(aCircleBuilder);
+ }
+
+ Circ2dPtr getProperCircle(const std::shared_ptr<GccAna_Circ2d2TanRad>& theBuilder) const
+ {
+ if (!theBuilder)
+ return Circ2dPtr();
+
+ int aNbSol = theBuilder->NbSolutions();
+ if (aNbSol == 0)
+ return Circ2dPtr();
+
+ int anAppropriateSolution = 1;
+ double aMinDist = Precision::Infinite();
+
+ double aParSol, aPonTgCurve;
+ gp_Pnt2d aTgPnt;
+ for (int i = 1; i <= aNbSol; ++i) {
+ bool isApplicable = false;
+ if (myTangentShapes.size() >= 1) {
+ theBuilder->Tangency1(i, aParSol, aPonTgCurve, aTgPnt);
+ isApplicable = isParamInCurve(aPonTgCurve, myTangentShapes[0]);
+ }
+ if (myTangentShapes.size() >= 2 && isApplicable) {
+ theBuilder->Tangency2(i, aParSol, aPonTgCurve, aTgPnt);
+ isApplicable = isParamInCurve(aPonTgCurve, myTangentShapes[1]);
+ }
+
+ if (isApplicable) {
+ double aDist = distanceToClosestPoint(theBuilder->ThisSolution(i));
+ if (aDist < aMinDist) {
+ anAppropriateSolution = i;
+ aMinDist = aDist;
+ }
+ }
+ }
+
+ return Circ2dPtr(new gp_Circ2d(theBuilder->ThisSolution(anAppropriateSolution)));
+ }
+
+
+ void convertTangentCurvesToGccEnt(VectorOfGccCirc& theTangentCircles,
+ VectorOfGccLine& theTangentLines)
+ {
+ theTangentCircles.reserve(3);
+ theTangentLines.reserve(3);
+
+ std::vector<CurveAdaptorPtr>::iterator anIt = myTangentShapes.begin();
+ for (; anIt != myTangentShapes.end(); ++anIt) {
+ switch ((*anIt)->GetType()) {
+ case GeomAbs_Line:
+ theTangentLines.push_back(
+ std::shared_ptr<GccEnt_QualifiedLin>(
+ new GccEnt_QualifiedLin((*anIt)->Line(), GccEnt_unqualified))
+ );
+ break;
+ case GeomAbs_Circle:
+ theTangentCircles.push_back(
+ std::shared_ptr<GccEnt_QualifiedCirc>(
+ new GccEnt_QualifiedCirc((*anIt)->Circle(), GccEnt_unqualified))
+ );
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+
+ // boundary parameters of curve are NOT applied
+ static bool isParamInCurve(double& theParameter, const CurveAdaptorPtr& theCurve)
+ {
+ if (theCurve->Curve()->IsPeriodic()) {
+ theParameter = ElCLib::InPeriod(theParameter,
+ theCurve->FirstParameter(),
+ theCurve->FirstParameter() + theCurve->Period());
+ }
+ return theParameter > theCurve->FirstParameter() &&
+ theParameter < theCurve->LastParameter();
+ }
+
+ // boundary parameters of curve are applied too
+ static bool isParamOnCurve(double& theParameter, const CurveAdaptorPtr& theCurve)
+ {
+ if (theCurve->IsPeriodic()) {
+ theParameter = ElCLib::InPeriod(theParameter,
+ theCurve->FirstParameter(),
+ theCurve->FirstParameter() + theCurve->Period());
+ }
+ return theParameter >= theCurve->FirstParameter() &&
+ theParameter <= theCurve->LastParameter();
+ }
+
+private:
+ Handle(Geom_Plane) myPlane;
+ std::shared_ptr<GeomAPI_Pnt2d> myCenter;
+ std::vector<gp_Pnt2d> myPassingPoints;
+ std::vector<CurveAdaptorPtr> myTangentShapes;
+ double myRadius;
+ std::shared_ptr<GeomAPI_Pnt2d> myClosestPoint;
+};
+
+
+
+
+
+GeomAlgoAPI_Circ2dBuilder::GeomAlgoAPI_Circ2dBuilder(const std::shared_ptr<GeomAPI_Ax3>& thePlane)
+ : myPlane(thePlane),
+ myRadius(0.)
+{
+}
+
+void GeomAlgoAPI_Circ2dBuilder::setRadius(const double theRadius)
+{
+ myRadius = theRadius;
+}
+
+void GeomAlgoAPI_Circ2dBuilder::setCenter(const std::shared_ptr<GeomAPI_Pnt2d>& theCenter)
+{
+ myCenter = theCenter;
+}
+
+void GeomAlgoAPI_Circ2dBuilder::addTangentCurve(const std::shared_ptr<GeomAPI_Shape>& theEdge)
+{
+ if (theEdge->isEdge())
+ myTangentShapes.push_back(theEdge);
+}
+
+void GeomAlgoAPI_Circ2dBuilder::addPassingPoint(const std::shared_ptr<GeomAPI_Pnt2d>& thePoint)
+{
+ myPassingPoints.push_back(thePoint);
+}
+
+void GeomAlgoAPI_Circ2dBuilder::setClosestPoint(const std::shared_ptr<GeomAPI_Pnt2d>& thePoint)
+{
+ myClosestPoint = thePoint;
+}
+
+std::shared_ptr<GeomAPI_Circ2d> GeomAlgoAPI_Circ2dBuilder::circle(
+ const std::shared_ptr<GeomAPI_Pnt2d>& theFirstPoint,
+ const std::shared_ptr<GeomAPI_Pnt2d>& theSecondPoint,
+ const std::shared_ptr<GeomAPI_Pnt2d>& theThirdPoint)
+{
+ std::shared_ptr<GeomAPI_Ax3> aPlane(new GeomAPI_Ax3);
+
+ GeomAlgoAPI_Circ2dBuilder aBuilder(aPlane);
+ aBuilder.addPassingPoint(theFirstPoint);
+ aBuilder.addPassingPoint(theSecondPoint);
+ aBuilder.addPassingPoint(theThirdPoint);
+ return aBuilder.circle();
+}
+
+std::shared_ptr<GeomAPI_Circ2d> GeomAlgoAPI_Circ2dBuilder::circle()
+{
+ CircleBuilder aCircleBuilder(myPlane);
+ aCircleBuilder.setCenter(myCenter);
+ aCircleBuilder.setTangentCurves(myTangentShapes);
+ aCircleBuilder.setPassingPoints(myPassingPoints);
+ aCircleBuilder.setClosestPoint(myClosestPoint);
+ aCircleBuilder.setRadius(myRadius);
+ Circ2dPtr aCirc2d = aCircleBuilder.circle();
+
+ std::shared_ptr<GeomAPI_Circ2d> aCircle;
+ if (aCirc2d) {
+ const gp_Pnt2d& aCenter = aCirc2d->Location();
+ const gp_Dir2d& aXAxis = aCirc2d->XAxis().Direction();
+
+ std::shared_ptr<GeomAPI_Pnt2d> aCircleCenter(new GeomAPI_Pnt2d(aCenter.X(), aCenter.Y()));
+ std::shared_ptr<GeomAPI_Dir2d> aCircleDir(new GeomAPI_Dir2d(aXAxis.X(), aXAxis.Y()));
+
+ aCircle = std::shared_ptr<GeomAPI_Circ2d>(
+ new GeomAPI_Circ2d(aCircleCenter, aCircleDir, aCirc2d->Radius()));
+ }
+ return aCircle;
+}
--- /dev/null
+// Copyright (C) 2017-20xx CEA/DEN, EDF R&D
+
+// File: GeomAlgoAPI_Circ2dBuilder.h
+// Created: 3 April 2017
+// Author: Artem ZHIDKOV
+
+#ifndef GeomAlgoAPI_Circ2dBuilder_H_
+#define GeomAlgoAPI_Circ2dBuilder_H_
+
+#include <GeomAlgoAPI.h>
+
+#include <memory>
+#include <vector>
+
+class GeomAPI_Ax3;
+class GeomAPI_Circ2d;
+class GeomAPI_Pnt2d;
+class GeomAPI_Shape;
+
+/// \class GeomAlgoAPI_Circ2dBuilder
+/// \ingroup DataAlgo
+/// \brief Creates circle in 2D space satisfying combination of the following constraints:
+/// * center of a circle
+/// * passing through the point
+/// * tangent to a curve
+/// * fixed radius
+class GeomAlgoAPI_Circ2dBuilder
+{
+public:
+ /// \brief Create a builder object.
+ /// Constraints should be applied separately.
+ /// \param thePlane [in] plane to project tangent curves
+ GEOMALGOAPI_EXPORT
+ GeomAlgoAPI_Circ2dBuilder(const std::shared_ptr<GeomAPI_Ax3>& thePlane);
+
+ /// \brief Set fixed radius of the circle
+ GEOMALGOAPI_EXPORT
+ void setRadius(const double theRadius);
+
+ /// \brief Set fixed center of the circle
+ GEOMALGOAPI_EXPORT
+ void setCenter(const std::shared_ptr<GeomAPI_Pnt2d>& theCenter);
+
+ /// \brief Constrain circle to be tangent to the given edge
+ GEOMALGOAPI_EXPORT
+ void addTangentCurve(const std::shared_ptr<GeomAPI_Shape>& theEdge);
+
+ /// \brief Constrain circle to pass through the given point
+ GEOMALGOAPI_EXPORT
+ void addPassingPoint(const std::shared_ptr<GeomAPI_Pnt2d>& thePoint);
+
+ /// \brief Optional constraint to find circle closest to the given point
+ GEOMALGOAPI_EXPORT
+ void setClosestPoint(const std::shared_ptr<GeomAPI_Pnt2d>& thePoint);
+
+ /// \brief Build circle
+ GEOMALGOAPI_EXPORT
+ std::shared_ptr<GeomAPI_Circ2d> circle();
+
+ /// \brief Create a circle passing through three points
+ GEOMALGOAPI_EXPORT
+ static std::shared_ptr<GeomAPI_Circ2d>
+ circle(const std::shared_ptr<GeomAPI_Pnt2d>& theFirstPoint,
+ const std::shared_ptr<GeomAPI_Pnt2d>& theSecondPoint,
+ const std::shared_ptr<GeomAPI_Pnt2d>& theThirdPoint);
+
+private:
+ std::shared_ptr<GeomAPI_Ax3> myPlane;
+ std::shared_ptr<GeomAPI_Pnt2d> myCenter;
+ std::vector< std::shared_ptr<GeomAPI_Pnt2d> > myPassingPoints;
+ std::vector< std::shared_ptr<GeomAPI_Shape> > myTangentShapes;
+ std::shared_ptr<GeomAPI_Pnt2d> myClosestPoint;
+ double myRadius;
+};
+
+#endif
return true;
}
-//==================================================================================================
-bool GeomAlgoAPI_ShapeTools::isShapesIntersects(
- const std::shared_ptr<GeomAPI_Shape> theShape1,
- const std::shared_ptr<GeomAPI_Shape> theShape2)
-{
- if(!theShape1.get() || !theShape2.get()) {
- return false;
- }
-
- const TopoDS_Shape& aShape1 = theShape1->impl<TopoDS_Shape>();
- const TopoDS_Shape& aShape2 = theShape2->impl<TopoDS_Shape>();
-
- BRepExtrema_DistShapeShape aDist(aShape1, aShape2);
- aDist.Perform();
- if(aDist.IsDone() && aDist.Value() < Precision::Confusion()) {
- return true;
- }
-
- return false;
-}
-
//==================================================================================================
bool GeomAlgoAPI_ShapeTools::isShapeValid(const std::shared_ptr<GeomAPI_Shape> theShape)
{
const std::shared_ptr<GeomAPI_Shape> theSubShape,
const std::shared_ptr<GeomAPI_Shape> theBaseShape);
- /// \brief Checks that shapes intersects.
- /// \param[in] theShape1 first shape.
- /// \param[in] theShape2 second shape.
- /// \return true if shapes intersects.
- GEOMALGOAPI_EXPORT static bool GeomAlgoAPI_ShapeTools::isShapesIntersects(
- const std::shared_ptr<GeomAPI_Shape> theShape1,
- const std::shared_ptr<GeomAPI_Shape> theShape2);
-
/// \return true if theShape is valid.
GEOMALGOAPI_EXPORT static bool isShapeValid(const std::shared_ptr<GeomAPI_Shape> theShape);
#include <ModelAPI_AttributeInteger.h>
#include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_ResultCompSolid.h>
+#include <ModelAPI_Tools.h>
//=================================================================================================
bool GeomValidators_BooleanArguments::isValid(const std::shared_ptr<ModelAPI_Feature>& theFeature,
std::list<std::string>::const_iterator anIt = theArguments.begin(), aLast = theArguments.end();
- std::shared_ptr<ModelAPI_AttributeSelectionList> anAttrSelList = theFeature->selectionList(*anIt);
+ bool isAllInSameCompSolid = true;
+ ResultCompSolidPtr aCompSolid;
+
+ AttributeSelectionListPtr anAttrSelList = theFeature->selectionList(*anIt);
if(anAttrSelList) {
anObjectsNb = anAttrSelList->size();
+ for(int anIndex = 0; anIndex < anObjectsNb; ++anIndex) {
+ AttributeSelectionPtr anAttr = anAttrSelList->value(anIndex);
+ ResultPtr aContext = anAttr->context();
+ ResultCompSolidPtr aResCompSolidPtr = ModelAPI_Tools::compSolidOwner(aContext);
+ if(aResCompSolidPtr.get()) {
+ if(aCompSolid.get()) {
+ isAllInSameCompSolid = aCompSolid == aResCompSolidPtr;
+ } else {
+ aCompSolid = aResCompSolidPtr;
+ }
+ } else {
+ isAllInSameCompSolid = false;
+ }
+ }
}
anIt++;
+
anAttrSelList = theFeature->selectionList(*anIt);
if(anAttrSelList) {
aToolsNb = anAttrSelList->size();
+ for(int anIndex = 0; anIndex < aToolsNb; ++anIndex) {
+ AttributeSelectionPtr anAttr = anAttrSelList->value(anIndex);
+ ResultPtr aContext = anAttr->context();
+ ResultCompSolidPtr aResCompSolidPtr = ModelAPI_Tools::compSolidOwner(aContext);
+ if(aResCompSolidPtr.get()) {
+ if(aCompSolid.get()) {
+ isAllInSameCompSolid = aCompSolid == aResCompSolidPtr;
+ } else {
+ aCompSolid = aResCompSolidPtr;
+ }
+ } else {
+ isAllInSameCompSolid = false;
+ }
+ }
}
anIt++;
anOperationType = anAttrInt->value();
}
- if(anOperationType == 1 && (anObjectsNb + aToolsNb > 1)) {
- return true;
- } else if (anOperationType != 1 && anObjectsNb > 0 && aToolsNb > 0) {
- return true;
+ if(anOperationType == 1) {
+ // Fuse operation
+ if(anObjectsNb + aToolsNb < 2) {
+ theError = "Not enough arguments for Fuse operation.";
+ return false;
+ } else if(isAllInSameCompSolid) {
+ theError = "Operations only between sub-shapes of the same shape not allowed.";
+ return false;
+ }
+ } else {
+ if(anObjectsNb < 1) {
+ theError = "Objects not selected.";
+ return false;
+ }
+ if(aToolsNb < 1) {
+ theError = "Tools not selected.";
+ return false;
+ }
+ if(isAllInSameCompSolid) {
+ theError = "Operations only between sub-shapes of the same shape not allowed.";
+ return false;
+ }
}
- theError = "Not enough arguments";
- return false;
+ return true;
}
//=================================================================================================
}
}
setValue(aCont, aShapeToBeSelected);
+ return;
}
+
+ TDF_Label aSelLab = selectionLabel();
+ setInvalidIfFalse(aSelLab, false);
+ reset();
}
int Model_AttributeSelection::Id()
bool Model_Document::save(
const char* theDirName, const char* theFileName, std::list<std::string>& theResults)
{
+ // if the history line is not in the end, move it to the end before save, otherwise
+ // problems with results restore and (the most important) naming problems will appear
+ // due to change evolution to SELECTION (problems in NamedShape and Name)
+ FeaturePtr aWasCurrent;
+ std::shared_ptr<Model_Session> aSession =
+ std::dynamic_pointer_cast<Model_Session>(Model_Session::get());
+ if (currentFeature(false) != lastFeature()) {
+ aSession->setCheckTransactions(false);
+ aWasCurrent = currentFeature(false);
+ setCurrentFeature(lastFeature(), false);
+ }
// create a directory in the root document if it is not yet exist
Handle(Model_Application) anApp = Model_Application::getApplication();
if (isRoot()) {
Handle(Standard_Failure) aFail = Standard_Failure::Caught();
Events_InfoMessage("Model_Document",
"Exception in saving of document: %1").arg(aFail->GetMessageString()).send();
+ if (aWasCurrent.get()) { // return the current feature to the initial position
+ setCurrentFeature(aWasCurrent, false);
+ aSession->setCheckTransactions(true);
+ }
return false;
}
bool isDone = aStatus == PCDM_SS_OK || aStatus == PCDM_SS_No_Obj;
break;
}
}
+
+ if (aWasCurrent.get()) { // return the current feature to the initial position
+ setCurrentFeature(aWasCurrent, false);
+ aSession->setCheckTransactions(true);
+ }
+
myTransactionSave = int(myTransactions.size());
if (isDone) { // save also sub-documents if any
theResults.push_back(TCollection_AsciiString(aPath).ToCString());
}
myObjs->synchronizeBackRefs();
Events_Loop* aLoop = Events_Loop::loop();
- aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED));
- aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
- aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
- aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_DELETED));
+ static const Events_ID kCreatedEvent = Events_Loop::loop()->eventByName(EVENT_OBJECT_CREATED);
+ static const Events_ID kUpdatedEvent = Events_Loop::loop()->eventByName(EVENT_OBJECT_UPDATED);
+ static const Events_ID kRedispEvent = Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY);
+ static const Events_ID kDeletedEvent = Events_Loop::loop()->eventByName(EVENT_OBJECT_DELETED);
+ aLoop->flush(kCreatedEvent);
+ aLoop->flush(kUpdatedEvent);
+ aLoop->flush(kRedispEvent);
+ aLoop->flush(kDeletedEvent);
if (isNestedClosed) {
if (myDoc->CommitCommand())
// to avoid messages about modifications outside of the transaction
// and to rebuild everything after all updates and creates
if (isRoot()) { // once for root document
- Events_Loop::loop()->autoFlush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
static std::shared_ptr<Events_Message> aFinishMsg
(new Events_Message(Events_Loop::eventByName("FinishOperation")));
Events_Loop::loop()->send(aFinishMsg);
- Events_Loop::loop()->autoFlush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED), false);
}
+
+ while(aLoop->hasGrouppedEvent(kCreatedEvent) || aLoop->hasGrouppedEvent(kUpdatedEvent) ||
+ aLoop->hasGrouppedEvent(kRedispEvent) || aLoop->hasGrouppedEvent(kDeletedEvent)) {
+ aLoop->flush(kCreatedEvent);
+ aLoop->flush(kUpdatedEvent);
+ aLoop->flush(kRedispEvent);
+ aLoop->flush(kDeletedEvent);
+ }
+
// to avoid "updated" message appearance by updater
//aLoop->clear(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
// add it after all nested (otherwise the nested will be disabled)
CompositeFeaturePtr aCompositeAfter =
std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(theAfterThis);
+ FeaturePtr anAfterThisSub = theAfterThis;
if (aCompositeAfter.get()) {
FeaturePtr aSub = aCompositeAfter;
do {
FeaturePtr aNext = myObjs->nextFeature(aSub);
if (!isSub(aCompositeAfter, aNext)) {
- theAfterThis = aSub;
+ anAfterThisSub = aSub;
break;
}
aSub = aNext;
} while (aSub.get());
}
- myObjs->moveFeature(theMoved, theAfterThis);
+ myObjs->moveFeature(theMoved, anAfterThisSub);
if (aCurrentUp) { // make the moved feature enabled or disabled due to the real status
setCurrentFeature(currentFeature(false), false);
- } else if (theAfterThis == currentFeature(false)) {
+ } else if (theAfterThis == currentFeature(false) || anAfterThisSub == currentFeature(false)) {
// must be after move to make enabled all features which are before theMoved
setCurrentFeature(theMoved, true);
}
if (!aNewP->partDoc().get())
// create the part result: it is better to restore the previous result if it is possible
theFeature->execute();
- break;
} else if (aGroup->Get() == ModelAPI_ResultConstruction::group().c_str()) {
theFeature->execute(); // construction shapes are needed for sketch solver
- break;
} else if (aGroup->Get() == ModelAPI_ResultGroup::group().c_str()) {
aNewBody = createGroup(theFeature->data(), aResIndex);
} else if (aGroup->Get() == ModelAPI_ResultField::group().c_str()) {
aNewBody = createField(theFeature->data(), aResIndex);
} else if (aGroup->Get() == ModelAPI_ResultParameter::group().c_str()) {
theFeature->attributeChanged("expression"); // just produce a value
- break;
} else {
Events_InfoMessage("Model_Objects", "Unknown type of result is found in the document:")
.arg(TCollection_AsciiString(aGroup->Get()).ToCString()).send();
#include <ModelAPI_ResultPart.h>
#include <ModelAPI_Tools.h>
+#include <TDF_ChildIDIterator.hxx>
#include <TDF_CopyTool.hxx>
#include <TDF_DataSet.hxx>
#include <TDF_RelocationTable.hxx>
#include <TDF_ClosureTool.hxx>
+#include <TNaming_Builder.hxx>
+#include <TNaming_Iterator.hxx>
+#include <TNaming_NamedShape.hxx>
+
+#include <TopoDS_Shape.hxx>
+
static Model_Session* myImpl = new Model_Session();
// t oredirect all calls to the root document
aRT->SetRelocation(aSourceRoot, aTargetRoot);
TDF_CopyTool::Copy(aDS, aRT);
+ // TODO: remove after fix in OCCT.
+ // All named shapes are stored in reversed order, so to fix this we reverse them back.
+ for(TDF_ChildIDIterator aChildIter(aTargetRoot, TNaming_NamedShape::GetID(), true);
+ aChildIter.More();
+ aChildIter.Next()) {
+ Handle(TNaming_NamedShape) aNamedShape =
+ Handle(TNaming_NamedShape)::DownCast(aChildIter.Value());
+ if (aNamedShape.IsNull()) {
+ continue;
+ }
+
+ TopoDS_Shape aShape = aNamedShape->Get();
+ if(aShape.IsNull() || aShape.ShapeType() != TopAbs_COMPOUND) {
+ continue;
+ }
+
+ TNaming_Evolution anEvol = aNamedShape->Evolution();
+ std::list<std::pair<TopoDS_Shape, TopoDS_Shape> > aShapePairs; // to store old and new shapes
+ for(TNaming_Iterator anIter(aNamedShape); anIter.More(); anIter.Next()) {
+ aShapePairs.push_back(
+ std::pair<TopoDS_Shape, TopoDS_Shape>(anIter.OldShape(), anIter.NewShape()));
+ }
+
+ // Add in reverse order.
+ TDF_Label aLabel = aNamedShape->Label();
+ TNaming_Builder aBuilder(aLabel);
+ for(std::list<std::pair<TopoDS_Shape, TopoDS_Shape> >::iterator aPairsIter =
+ aShapePairs.begin();
+ aPairsIter != aShapePairs.end();
+ aPairsIter++) {
+ if (anEvol == TNaming_GENERATED) {
+ aBuilder.Generated(aPairsIter->first, aPairsIter->second);
+ } else if (anEvol == TNaming_MODIFY) {
+ aBuilder.Modify(aPairsIter->first, aPairsIter->second);
+ } else if (anEvol == TNaming_DELETE) {
+ aBuilder.Delete(aPairsIter->first);
+ } else if (anEvol == TNaming_PRIMITIVE) {
+ aBuilder.Generated(aPairsIter->second);
+ } else if (anEvol == TNaming_SELECTED) {
+ aBuilder.Select(aPairsIter->second, aPairsIter->first);
+ }
+ }
+ }
+
TDF_LabelList anEmptyUpdated;
aNew->objects()->synchronizeFeatures(anEmptyUpdated, true, true, true, true);
return aNew;
(*aRIter)->attributeChanged("External");
}
}
- // send event that sketch is prepared to be recomputed
- static Events_ID anID = Events_Loop::eventByName("SketchPrepared");
- std::shared_ptr<Events_Message> aMsg(new Events_Message(anID, this));
- Events_Loop::loop()->send(aMsg);
}
if (!aIsModified) { // no modification is needed
for(; aValidatorIt != aValidators.cend(); aValidatorIt++) {
const std::string& aValidatorID = aValidatorIt->first;
const std::list<std::string>& anArguments = aValidatorIt->second;
- // validators() checks invalid validator names
- //if (!aValidator) {
- // Events_Error::send(std::string("Validator ") + aValidatorID + " was not registered");
- // continue;
- //}
const ModelAPI_FeatureValidator* aFValidator =
dynamic_cast<const ModelAPI_FeatureValidator*>(validator(aValidatorID));
if (aFValidator) {
}
}
}
- // The default validator was retrned by validators() and was checked in previous cycle
- //// check default validator
- //std::map<std::string, ModelAPI_Validator*>::const_iterator aDefaultVal = myIDs.find(kDefaultId);
- //if(aDefaultVal != myIDs.end()) {
- // static const std::list<std::string> anEmptyArgList;
- // const ModelAPI_FeatureValidator* aFValidator =
- // dynamic_cast<const ModelAPI_FeatureValidator*>(aDefaultVal->second);
- // if (aFValidator) {
- // std::string anError;
- // if (!aFValidator->isValid(theFeature, anEmptyArgList, anError)) {
- // if (anError.empty())
- // anError = "Unknown error.";
- // anError = "Feature invalidated by \"" + kDefaultId + "\" with error: " + anError;
- // theFeature->setError(anError, false);
- // theFeature->data()->execState(ModelAPI_StateInvalidArgument);
- // return false;
- // }
- // }
- //}
// check all attributes for validity
- // Validity of data is checked by "Model_FeatureValidator" (kDefaultId)
- // if (!aData || !aData->isValid())
- // return false;
static const std::string kAllTypes = "";
std::list<std::string> aLtAttributes = aData->attributesIDs(kAllTypes);
std::list<std::string>::const_iterator anAttrIt = aLtAttributes.cbegin();
ModelAPI_CompositeFeature.h
ModelAPI_Data.h
ModelAPI_Document.h
+ ModelAPI_EventReentrantMessage.h
ModelAPI_Events.h
ModelAPI_Expression.h
ModelAPI_Feature.h
ModelAPI_FeatureValidator.h
+ ModelAPI_IReentrant.h
ModelAPI_Object.h
ModelAPI_Plugin.h
ModelAPI_Result.h
ModelAPI_CompositeFeature.cpp
ModelAPI_Data.cpp
ModelAPI_Document.cpp
+ ModelAPI_EventReentrantMessage.cpp
ModelAPI_Events.cpp
ModelAPI_Expression.cpp
ModelAPI_Feature.cpp
ModelAPI_FeatureValidator.cpp
+ ModelAPI_IReentrant.cpp
ModelAPI_Object.cpp
ModelAPI_Plugin.cpp
ModelAPI_Result.cpp
%{
#include "ModelAPI_swig.h"
-
- // fix for SWIG v2.0.4
- #define SWIGPY_SLICE_ARG(obj) ((PySliceObject*)(obj))
%}
// import other modules
%template(modelAPI_AttributeRefAttrList) shared_ptr_cast<ModelAPI_AttributeRefAttrList, ModelAPI_Attribute>;
%template(modelAPI_AttributeTables) shared_ptr_cast<ModelAPI_AttributeTables, ModelAPI_Attribute>;
+%template(PointList) std::list<std::shared_ptr<GeomAPI_Pnt> >;
+%template(PointSet) std::set<std::shared_ptr<GeomAPI_Pnt> >;
+
// Geometry casts
%template(shapeToEdge) shared_ptr_cast<GeomAPI_Edge, GeomAPI_Shape>;
--- /dev/null
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
+
+// File: ModelAPI_EventReentrantMessage.cpp
+// Created: 30 Mar 2017
+// Author: Natalia ERMOLAEVA
+
+#include <ModelAPI_EventReentrantMessage.h>
+
+ModelAPI_EventReentrantMessage::ModelAPI_EventReentrantMessage(
+ const Events_ID theID,
+ const void* theSender)
+: Events_Message(theID, theSender)
+{
+}
--- /dev/null
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
+
+// File: ModelAPI_EventReentrantMessage.h
+// Created: 30 Mar 2017
+// Author: Natalia ERMOLAEVA
+
+#ifndef ModelAPI_EventReentrantMessage_H_
+#define ModelAPI_EventReentrantMessage_H_
+
+#include <Events_Message.h>
+#include <Events_Loop.h>
+
+#include <ModelAPI.h>
+
+#include <memory>
+
+class ModelAPI_Object;
+class ModelAPI_Feature;
+class ModelAPI_Attribute;
+class GeomAPI_Pnt2d;
+
+/// Message that style of visualization of parameter is changed.
+/// It will be shown as expression or value
+class ModelAPI_EventReentrantMessage : public Events_Message
+{
+public:
+ /// Creates an empty message
+ MODELAPI_EXPORT ModelAPI_EventReentrantMessage(const Events_ID theID,
+ const void* theSender = 0);
+ /// The virtual destructor
+ MODELAPI_EXPORT virtual ~ModelAPI_EventReentrantMessage() {}
+ /// Static. Returns EventID of the message.
+ MODELAPI_EXPORT static Events_ID eventId()
+ {
+ static const char * MY_EVENT_REENTRANT_MESSAGE_ID("EventReentrantMessage");
+ return Events_Loop::eventByName(MY_EVENT_REENTRANT_MESSAGE_ID);
+ }
+
+ /// Fills previous feature parameter
+ MODELAPI_EXPORT void setCreatedFeature(const std::shared_ptr<ModelAPI_Feature>& theFeature)
+ { myCreatedFeature = theFeature; }
+
+ /// Returns previous feature parameter
+ MODELAPI_EXPORT const std::shared_ptr<ModelAPI_Feature>& createdFeature() const
+ { return myCreatedFeature; }
+
+ /// Fills selected object parameter
+ /// \theObject a feature or result
+ MODELAPI_EXPORT void setSelectedObject(const std::shared_ptr<ModelAPI_Object>& theObject)
+ { mySelectedObject = theObject; }
+
+ /// Returns selected object parameter
+ MODELAPI_EXPORT const std::shared_ptr<ModelAPI_Object>& selectedObject() const
+ { return mySelectedObject; }
+
+ /// Fills selected attribute parameter
+ /// \theAttribute
+ MODELAPI_EXPORT void setSelectedAttribute
+ (const std::shared_ptr<ModelAPI_Attribute>& theAttribute)
+ { mySelectedAttribute = theAttribute; }
+
+ /// Returns selected attribute parameter
+ MODELAPI_EXPORT const std::shared_ptr<ModelAPI_Attribute>& selectedAttribute()
+ { return mySelectedAttribute; }
+
+ /// Fills clicked point
+ /// \thePoint
+ MODELAPI_EXPORT void setClickedPoint(const std::shared_ptr<GeomAPI_Pnt2d>& thePoint)
+ { myClickedPoint = thePoint; }
+
+ /// Returns clicked point
+ MODELAPI_EXPORT const std::shared_ptr<GeomAPI_Pnt2d>& clickedPoint()
+ { return myClickedPoint; }
+
+private:
+ std::shared_ptr<ModelAPI_Feature> myCreatedFeature; ///< previous object
+ std::shared_ptr<ModelAPI_Object> mySelectedObject; ///< selected object
+ std::shared_ptr<ModelAPI_Attribute> mySelectedAttribute; ///< selected attribute
+ std::shared_ptr<GeomAPI_Pnt2d> myClickedPoint; ///< clicked point
+};
+
+typedef std::shared_ptr<ModelAPI_EventReentrantMessage> ReentrantMessagePtr;
+
+
+#endif
myResults.push_back(theResult);
}
// in any case result becomes enabled
- theResult->setDisabled(theResult, false);
+ if (!isDisabled()) // disabled feature may be executed when it is added as not enabled (#2078)
+ theResult->setDisabled(theResult, false);
}
void ModelAPI_Feature::setResult(const std::shared_ptr<ModelAPI_Result>& theResult,
--- /dev/null
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File: ModelAPI_IReentrant.cpp
+// Created: 30 Mar 2017
+// Author: Natalia ERMOLAEVA
+
+#include <ModelAPI_IReentrant.h>
+
+ModelAPI_IReentrant::~ModelAPI_IReentrant()
+{
+}
--- /dev/null
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File: ModelAPI_IReentrant.hxx
+// Created: 30 Mar 2017
+// Author: Natalia ERMOLAEVA
+
+#ifndef ModelAPI_IReentrant_H
+#define ModelAPI_IReentrant_H
+
+#include "ModelAPI.h"
+
+#include <vector>
+#include <memory>
+
+class Events_Message;
+
+/** \class ModelAPI_IReentrant
+ * \ingroup DataModel
+ * \brief Interface of a class which can process specific messages
+ */
+class ModelAPI_IReentrant
+{
+public:
+ MODELAPI_EXPORT virtual ~ModelAPI_IReentrant();
+
+ /// Apply information of the message to current object.
+ /// \param theMessage a container of information
+ /// \return a next active attribute name
+ virtual std::string processEvent(const std::shared_ptr<Events_Message>& theMessage) = 0;
+};
+
+typedef std::shared_ptr<ModelAPI_IReentrant> ModelReentrantPtr;
+
+#endif
aSketchFeature2 = featureToCompositeFeature(aPart.addFeature("Sketch"))
aSketchFeature2.selection("External").setValue(aXOYPlane, None);
aCirc1 = aSketchFeature2.addFeature("SketchCircle")
-geomDataAPI_Point2D(aCirc1.attribute("CircleCenter")).setValue(100, 50)
-aCirc1.real("CircleRadius").setValue(40)
+geomDataAPI_Point2D(aCirc1.attribute("circle_center")).setValue(100, 50)
+aCirc1.real("circle_radius").setValue(40)
aSession.finishOperation()
#=========================================================================
aSketchFeature3 = featureToCompositeFeature(aPart.addFeature("Sketch"))
aSketchFeature3.selection("External").setValue(aXOYPlane, None);
aCirc2 = aSketchFeature3.addFeature("SketchCircle")
-geomDataAPI_Point2D(aCirc2.attribute("CircleCenter")).setValue(20, 20)
-aCirc2.real("CircleRadius").setValue(10)
+geomDataAPI_Point2D(aCirc2.attribute("circle_center")).setValue(20, 20)
+aCirc2.real("circle_radius").setValue(10)
aSession.finishOperation()
#=========================================================================
}
}
-void ModelGeomAlgo_Point2D::getPointsIntersectedShape(const std::shared_ptr<ModelAPI_Feature>& theBaseFeature,
+void ModelGeomAlgo_Point2D::getPointsIntersectedShape(
+ const std::shared_ptr<ModelAPI_Feature>& theBaseFeature,
const std::list<std::shared_ptr<ModelAPI_Feature> >& theFeatures,
PointToRefsMap& thePointToAttributeOrObject)
{
/// \param isSkipFeatureAttributes a boolean value if coincidences to the feature attributes
/// should be skipped
/// \returns found point attribute or NULL
- static MODELGEOMALGO_EXPORT void getPointsOfReference(const std::shared_ptr<ModelAPI_Object>& theObject,
+ static MODELGEOMALGO_EXPORT
+ void getPointsOfReference(const std::shared_ptr<ModelAPI_Object>& theObject,
const std::string& theReferenceFeatureKind,
std::set<std::shared_ptr<GeomDataAPI_Point2D> >& theAttributes,
const std::string& theObjectFeatureKind = "",
#include <ModelAPI_AttributeIntArray.h>
#include <ModelAPI_AttributeSelection.h>
#include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_Feature.h>
#include <ModelAPI_ResultCompSolid.h>
//--------------------------------------------------------------------------------------
return;
case VT_TypeSubShapeNamePair:
theAttribute->selectSubShape(myTypeSubShapeNamePair.first, myTypeSubShapeNamePair.second);
+ if(theAttribute->isInvalid()) {
+ FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
+ aFeature->setError(
+ std::string("Error: attribute \"") + theAttribute->id() + std::string("\" is invalid."));
+ }
return;
}
}
aDump->execute();
}
bool isProblem = !aDump.get() || !aDump->error().empty(); // after "finish" dump will be removed
+ if (isProblem && aDump.get()) {
+ std::cout<<"Dump feature error "<<aDump->error()<<std::endl;
+ Events_InfoMessage anErrorMsg(std::string("checkPythonDump"), aDump->error());
+ anErrorMsg.send();
+ }
aSession->finishOperation();
- if (isProblem)
+ if (isProblem) {
return false; // something is wrong during dump
+ }
// map from document name to feature name to feature data
std::map<std::string, std::map<std::string, ModelHighAPI_FeatureStore> > aStore;
#define ModuleBase_IErrorMgr_H
#include "ModuleBase.h"
+
#include <QObject>
+#include <memory>
+
class ModuleBase_IPropertyPanel;
+class ModelAPI_Feature;
/**
* \class ModuleBase_IErrorMgr
/// \return Currently installed property panel
ModuleBase_IPropertyPanel* propertyPanel() const { return myPropertyPanel; }
+ /// Update actions for the given feature
+ /// \param theFeature a feature
+ virtual void updateActions(const std::shared_ptr<ModelAPI_Feature>& theFeature) = 0;
+
protected slots:
/// Process values changed event for processing feature attribute validation errors.
virtual void onWidgetChanged() = 0;
// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+#include "ModelAPI_IReentrant.h"
+#include "ModelAPI_EventReentrantMessage.h"
#include "ModuleBase_IModule.h"
#include "ModuleBase_IViewer.h"
#include "ModuleBase_ViewerPrs.h"
#include "ModuleBase_Operation.h"
+#include "ModuleBase_IPropertyPanel.h"
#include "ModuleBase_ISelection.h"
#include "ModuleBase_OperationDescription.h"
#include "ModuleBase_OperationFeature.h"
#include "ModuleBase_WidgetFactory.h"
#include "ModuleBase_PageWidget.h"
#include "ModuleBase_Dialog.h"
+#include "ModuleBase_IErrorMgr.h"
#include <Events_Loop.h>
+#include <Events_Message.h>
#include <ModelAPI_Events.h>
#include <ModelAPI_CompositeFeature.h>
ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
(createOperation(theCmdId.toStdString()));
if (aFOperation) {
- aFOperation->initSelection(aPreSelected);
+ std::shared_ptr<Events_Message> aMessage = reentrantMessage();
+ if (aMessage.get()) {
+ setReentrantPreSelection(aMessage);
+ }
+ else
+ aFOperation->initSelection(aPreSelected);
workshop()->processLaunchOperation(aFOperation);
+
+ if (aFOperation) {
+ FeaturePtr aFeature = aFOperation->feature();
+ ModelReentrantPtr aReentrantFeature =
+ std::dynamic_pointer_cast<ModelAPI_IReentrant>(aFeature);
+ if (aReentrantFeature.get()) {
+ if (aMessage.get()) {
+ ModuleBase_IPropertyPanel* aPanel = workshop()->propertyPanel();
+ std::string aPrevAttribute = aReentrantFeature->processEvent(aMessage);
+ workshop()->errorMgr()->updateActions(aFeature);
+
+ ModuleBase_ModelWidget* aPrevWidget = aPanel->modelWidget(aPrevAttribute);
+ aPanel->activateNextWidget(aPrevWidget);
+ }
+ }
+ }
}
}
class Config_WidgetAPI;
class ModuleBase_ModelWidget;
class ModuleBase_Operation;
+class ModuleBase_ViewerPrs;
+
class ModuleBase_IWorkshop;
class ModelAPI_Result;
+class Events_Message;
class AIS_InteractiveObject;
AISObjectPtr thePrs,
GeomCustomPrsPtr theCustomPrs) { return false; };
+ /// Modifies the given presentation in the custom way after usual customize is performed.
+ virtual bool afterCustomisePresentation(std::shared_ptr<ModelAPI_Result> theResult,
+ AISObjectPtr thePrs,
+ GeomCustomPrsPtr theCustomPrs) { return false; };
+
/// Update the object presentable properties such as color, lines width and other
/// If the object is result with the color attribute value set, it is used,
/// otherwise the customize is applyed to the object's feature if it is a custom prs
virtual AttributePtr findAttribute(const ObjectPtr& theObject,
const GeomShapePtr& theGeomShape) = 0;
+ /// Returns reentrant message if it was accepted
+ virtual std::shared_ptr<Events_Message> reentrantMessage() = 0;
+
+ /// Put current selection into reentrant message
+ /// \param theMessage a message of reentrant operation
+ virtual void setReentrantPreSelection(const std::shared_ptr<Events_Message>& theMessage) = 0;
+
/// Returns XML information by the feature index
/// \param theFeatureId a feature id
/// \param theXmlCfg XML configuration
ModuleBase_IPropertyPanel::ModuleBase_IPropertyPanel(QWidget* theParent)
: QDockWidget(theParent), myIsEditing(false)
{
+}
+
+ModuleBase_ModelWidget* ModuleBase_IPropertyPanel::modelWidget(
+ const std::string& theAttributeId) const
+{
+ ModuleBase_ModelWidget* aWidget = 0;
+ QList<ModuleBase_ModelWidget*> aWidgets = modelWidgets();
+ ModelAPI_ValidatorsFactory* aValidators = ModelAPI_Session::get()->validators();
+ for (QList<ModuleBase_ModelWidget*>::const_iterator anIt = aWidgets.begin();
+ anIt != aWidgets.end() && !aWidget; anIt++) {
+ ModuleBase_ModelWidget* aCurrentWidget = *anIt;
+ if (aCurrentWidget->attributeID() == theAttributeId &&
+ aCurrentWidget->canAcceptFocus() &&
+ aValidators->isCase(aCurrentWidget->feature(), aCurrentWidget->attributeID()))
+ aWidget = aCurrentWidget;
+ }
+ return aWidget;
}
ModuleBase_ModelWidget* ModuleBase_IPropertyPanel::findFirstAcceptingValueWidget()
/// Returns all property panel's widget created by WidgetFactory
virtual const QList<ModuleBase_ModelWidget*>& modelWidgets() const = 0;
+ /// Returns widget, that has the given attribute index
+ /// \param theAttributeId an attribute from XML
+ virtual ModuleBase_ModelWidget* modelWidget(const std::string& theAttributeId) const;
+
/// Removes all widgets in the widget area of the property panel
virtual void cleanContent() = 0;
class ModuleBase_ISelection;
class ModuleBase_IViewer;
class ModuleBase_IPropertyPanel;
+class ModuleBase_IErrorMgr;
class ModuleBase_Operation;
class ModuleBase_ViewerPrs;
class QMainWindow;
//! Returns property panel
virtual ModuleBase_IPropertyPanel* propertyPanel() const = 0;
+ //! Returns error manager
+ virtual ModuleBase_IErrorMgr* errorMgr() const = 0;
+
/// A filter to process an attribute validators
/// \return a filter
Handle(ModuleBase_FilterValidated) validatorFilter();
myIsInternal = theData->getBooleanAttribute(ATTR_INTERNAL, false);
- myIsModifiedInEdit = theData->getBooleanAttribute(ATTR_MODIFIED_IN_EDIT, true);
+ myIsModifiedInEdit = theData->getProperty(ATTR_MODIFIED_IN_EDIT);
myDefaultValue = theData->getProperty(ATTR_DEFAULT);
myUseReset = theData->getBooleanAttribute(ATTR_USE_RESET, true);
bool isDone = false;
// value is stored only in creation mode and in edition if there is not
// XML flag prohibited modification in edit mode(macro feature circle/arc)
- if (!isEditingMode() || isModifiedInEdit())
+ if (!isEditingMode() || isModifiedInEdit().empty())
isDone = storeValueCustom();
+ else {
+ /// store value in an alternative attribute if possible(attribute has the same type)
+ std::string aWidgetAttribute = attributeID();
+ myAttributeID = isModifiedInEdit();
+ storeValueCustom();
+ myAttributeID = aWidgetAttribute;
+ // operation will be restarted but if isDone == true, PagedContainer will try to set focus
+ // to the current widget, but will be already deleted
+ isDone = false;
+ }
emit afterValuesChanged();
/// Returns this parameter value in the xml file
/// \return the boolean result
- bool isModifiedInEdit() const { return myIsModifiedInEdit; }
+ std::string isModifiedInEdit() const { return myIsModifiedInEdit; }
/// Returns this widget value state
/// \return the enumeration result
bool myIsInternal;
// an XML state, the value is not stored into model if the widget is in edit mode
- bool myIsModifiedInEdit;
+ std::string myIsModifiedInEdit;
/// the reset state. If it is false, the reset method of the widget is not performed
bool myUseReset;
norm = geomDataAPI_Dir(aSketchFeature.attribute("Norm"))
norm.setValue(0, 0, 1)
aSketchCircle = aSketchFeature.addFeature("SketchCircle")
- anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("CircleCenter"))
- aRadiusAttr = aSketchCircle.real("CircleRadius")
+ anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("circle_center"))
+ aRadiusAttr = aSketchCircle.real("circle_radius")
anCircleCentr.setValue(10., 20.)
aRadiusAttr.setValue(10.)
self.aSession.finishOperation()
#=========================================================================
aSession.startOperation()
aSketchCircle = aSketchFeature.addFeature("SketchCircle")
-anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("CircleCenter"))
-aRadiusAttr = aSketchCircle.real("CircleRadius")
+anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("circle_center"))
+aRadiusAttr = aSketchCircle.real("circle_radius")
anCircleCentr.setValue(250., 250)
aRadiusAttr.setValue(25.)
aSession.finishOperation()
norm = geomDataAPI_Dir(aSketchFeature.attribute("Norm"))
norm.setValue(0, 0, 1)
aSketchCircle = aSketchFeature.addFeature("SketchCircle")
- anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("CircleCenter"))
- aRadiusAttr = aSketchCircle.real("CircleRadius")
+ anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("circle_center"))
+ aRadiusAttr = aSketchCircle.real("circle_radius")
anCircleCentr.setValue(10., 20.)
aRadiusAttr.setValue(10.)
self.aSession.finishOperation()
break;
case ModuleBase_IModule::CustomizeResults:
PartSet_OperationPrs::getResultShapes(myFeature, myWorkshop, aFeatureShapes);
+ PartSet_OperationPrs::getPresentationShapes(myFeature, myWorkshop, aFeatureShapes);
break;
case ModuleBase_IModule::CustomizeHighlightedObjects:
PartSet_OperationPrs::getHighlightedShapes(myWorkshop, aFeatureShapes);
{
bool isEnabledFixed = false;
if (theActionId == XGUI_ActionsMgr::AcceptAll &&
- mySketchReentrantMgr->isInternalEditStarted())
+ mySketchReentrantMgr->isInternalEditActive())
isEnabledFixed = true;
return isEnabledFixed;
}
theTypes.append(SketcherPrs_Tools::Sel_Sketch_Wire);
}
+void PartSet_Module::getGeomSelection(const std::shared_ptr<ModuleBase_ViewerPrs>& theSelected,
+ ObjectPtr& theObject, AttributePtr& theAttribute)
+{
+ ObjectPtr anObject = theSelected->object();
+ GeomShapePtr aShape = theSelected->shape();
+
+ theAttribute = findAttribute(anObject, aShape);
+ // TODO: try to create result if object is an external object
+ theObject = anObject;
+}
+
bool PartSet_Module::isMouseOverWindow()
{
return mySketchMgr->isMouseOverWindow();
bool PartSet_Module::isSketchNeutralPointActivated() const
{
bool isNeutralPoint = true;
- if (sketchReentranceMgr()->isInternalEditStarted())
+ if (sketchReentranceMgr()->isInternalEditActive())
isNeutralPoint = false;
if (myIsOperationIsLaunched)
isNeutralPoint = false;
return aCustomized;
if (!theResult.get()) {
- bool isConflicting = myOverconstraintListener->isConflictingObject(anObject);
- // customize sketch symbol presentation
- if (thePrs.get()) {
- Handle(AIS_InteractiveObject) anAISIO = thePrs->impl<Handle(AIS_InteractiveObject)>();
- if (!anAISIO.IsNull()) {
- if (!Handle(SketcherPrs_SymbolPrs)::DownCast(anAISIO).IsNull()) {
- Handle(SketcherPrs_SymbolPrs) aPrs = Handle(SketcherPrs_SymbolPrs)::DownCast(anAISIO);
- if (!aPrs.IsNull()) {
- std::vector<int> aColor;
- myOverconstraintListener->getConflictingColor(aColor);
- aPrs->SetConflictingConstraint(isConflicting, aColor);
- aCustomized = true;
- }
- } else if (!Handle(SketcherPrs_Coincident)::DownCast(anAISIO).IsNull()) {
- Handle(SketcherPrs_Coincident) aPrs = Handle(SketcherPrs_Coincident)::DownCast(anAISIO);
- if (!aPrs.IsNull()) {
- std::vector<int> aColor;
- myOverconstraintListener->getConflictingColor(aColor);
- aPrs->SetConflictingConstraint(isConflicting, aColor);
- aCustomized = true;
- }
- }
- }
- }
- // customize sketch dimension constraint presentation
- if (!aCustomized) {
- std::vector<int> aColor;
- if (isConflicting) {
- myOverconstraintListener->getConflictingColor(aColor);
- }
- if (aColor.empty())
- XGUI_CustomPrs::getDefaultColor(anObject, true, aColor);
- if (!aColor.empty()) {
- aCustomized = thePrs->setColor(aColor[0], aColor[1], aColor[2]);
- }
+ std::vector<int> aColor;
+ XGUI_CustomPrs::getDefaultColor(anObject, true, aColor);
+ if (!aColor.empty()) {
+ aCustomized = thePrs->setColor(aColor[0], aColor[1], aColor[2]);
}
}
// customize dimentional constrains
return aCustomized;
}
+bool PartSet_Module::afterCustomisePresentation(std::shared_ptr<ModelAPI_Result> theResult,
+ AISObjectPtr thePrs,
+ GeomCustomPrsPtr theCustomPrs)
+{
+ bool aCustomized = false;
+
+ XGUI_Workshop* aWorkshop = getWorkshop();
+ XGUI_Displayer* aDisplayer = aWorkshop->displayer();
+ ObjectPtr anObject = aDisplayer->getObject(thePrs);
+ if (!anObject)
+ return aCustomized;
+
+ std::vector<int> aColor;
+ bool aUseCustomColor = true;
+ if (aUseCustomColor)
+ myOverconstraintListener->getCustomColor(anObject, aColor);
+ // customize sketch symbol presentation
+ Handle(AIS_InteractiveObject) anAISIO = thePrs->impl<Handle(AIS_InteractiveObject)>();
+ if (!anAISIO.IsNull()) {
+ if (!Handle(SketcherPrs_SymbolPrs)::DownCast(anAISIO).IsNull()) {
+ Handle(SketcherPrs_SymbolPrs) aPrs = Handle(SketcherPrs_SymbolPrs)::DownCast(anAISIO);
+ if (!aPrs.IsNull()) {
+ aPrs->SetCustomColor(aColor);
+ aCustomized = true;
+ }
+ } else if (!Handle(SketcherPrs_Coincident)::DownCast(anAISIO).IsNull()) {
+ Handle(SketcherPrs_Coincident) aPrs = Handle(SketcherPrs_Coincident)::DownCast(anAISIO);
+ if (!aPrs.IsNull()) {
+ aPrs->SetCustomColor(aColor);
+ aCustomized = true;
+ }
+ }
+ }
+ // customize sketch dimension constraint presentation
+ if (!aCustomized) {
+ if (!aColor.empty()) { // otherwise presentation has the default color
+ aCustomized = thePrs->setColor(aColor[0], aColor[1], aColor[2]);
+ }
+ }
+ return aCustomized;
+}
+
bool PartSet_Module::customizeObject(ObjectPtr theObject, const ModuleBase_CustomizeFlag& theFlag,
const bool theUpdateViewer)
{
return anAttribute;
}
+//******************************************************
+std::shared_ptr<Events_Message> PartSet_Module::reentrantMessage()
+{
+ return sketchReentranceMgr()->reentrantMessage();
+}
+
+//******************************************************
+void PartSet_Module::setReentrantPreSelection(const std::shared_ptr<Events_Message>& theMessage)
+{
+ sketchReentranceMgr()->setReentrantPreSelection(theMessage);
+}
+
//******************************************************
void PartSet_Module::onChoiceChanged(ModuleBase_ModelWidget* theWidget,
int theIndex)
class ModuleBase_Operation;
class ModuleBase_IViewWindow;
+class ModuleBase_ViewerPrs;
+
class XGUI_Workshop;
class PartSet_MenuMgr;
class PartSet_CustomPrs;
/// Returns sketch reentrant manager
PartSet_SketcherReentrantMgr* sketchReentranceMgr() const { return mySketchReentrantMgr; }
+ /// Find object and attribute(if selected) for the given viewer selection
+ /// \param theSelected a viewer selection
+ /// \param theObject a selected model object
+ /// \param theAttribute a selected model attribute
+ virtual void getGeomSelection(const std::shared_ptr<ModuleBase_ViewerPrs>& theSelected,
+ ObjectPtr& theObject, AttributePtr& theAttribute);
+
/// Returns listener of overconstraint signal
/// \return the listener
PartSet_OverconstraintListener* overconstraintListener() { return myOverconstraintListener; }
AISObjectPtr thePrs,
std::shared_ptr<GeomAPI_ICustomPrs> theCustomPrs);
+ /// Modifies the given presentation in the custom way after usual customize is performed.
+ virtual bool afterCustomisePresentation(std::shared_ptr<ModelAPI_Result> theResult,
+ AISObjectPtr thePrs,
+ GeomCustomPrsPtr theCustomPrs);
+
/// Update the object presentable properties such as color, lines width and other
/// If the object is result with the color attribute value set, it is used,
/// otherwise the customize is applyed to the object's feature if it is a custom prs
/// \return theAttribute
virtual AttributePtr findAttribute(const ObjectPtr& theObject, const GeomShapePtr& theGeomShape);
+ /// Returns reentrant message if it was accepted
+ virtual std::shared_ptr<Events_Message> reentrantMessage();
+
+ /// Put current selection into reentrant message
+ /// \param theMessage a message of reentrant operation
+ virtual void setReentrantPreSelection(const std::shared_ptr<Events_Message>& theMessage);
+
/// Returns the workshop
XGUI_Workshop* getWorkshop() const;
}
}
+void PartSet_OperationPrs::getPresentationShapes(const FeaturePtr& theFeature,
+ ModuleBase_IWorkshop* theWorkshop,
+ QMap<ObjectPtr, QList<GeomShapePtr> >& theObjectShapes,
+ const bool theListShouldBeCleared)
+{
+ if (theListShouldBeCleared)
+ theObjectShapes.clear();
+
+ if (!theFeature.get() || !theFeature->data()->isValid()) // if feature is already removed
+ return;
+
+ XGUI_Displayer* aDisplayer = XGUI_Tools::workshop(theWorkshop)->displayer();
+
+ GeomPresentablePtr aPrs = std::dynamic_pointer_cast<GeomAPI_IPresentable>(theFeature);
+ if (!aPrs.get())
+ return;
+
+ AISObjectPtr anAIS = aPrs->getAISObject(aDisplayer->getAISObject(theFeature));
+ if (!anAIS.get())
+ return;
+
+ Handle(AIS_InteractiveObject) anAISPrs = anAIS->impl<Handle(AIS_InteractiveObject)>();
+ if (!anAISPrs.IsNull()) {
+ Handle(AIS_Shape) aShapePrs = Handle(AIS_Shape)::DownCast(anAISPrs);
+ if (!aShapePrs.IsNull()) {
+ TopoDS_Shape aShape = aShapePrs->Shape();
+ if (!aShape.IsNull()) {
+ std::shared_ptr<GeomAPI_Shape> aGeomShape(new GeomAPI_Shape());
+ aGeomShape->setImpl(new TopoDS_Shape(aShape));
+ appendShapeIfVisible(theWorkshop, theFeature, aGeomShape, theObjectShapes);
+ }
+ }
+ }
+}
+
void PartSet_OperationPrs::getHighlightedShapes(ModuleBase_IWorkshop* theWorkshop,
QMap<ObjectPtr,
QList<GeomShapePtr> >& theObjectShapes)
QMap<ObjectPtr, QList<GeomShapePtr> >& theObjectShapes,
const bool theListShouldBeCleared = true);
+ /// Fills the map by the feature presentation if the feature is presentable
+ /// \param theFeature a current feature
+ /// \param theWorkshop a current workshop
+ /// \param theObjectShapes an output map
+ /// \param theObjectShape an output map of objects
+ static void getPresentationShapes(const FeaturePtr& theFeature,
+ ModuleBase_IWorkshop* theWorkshop,
+ QMap<ObjectPtr, QList<GeomShapePtr> >& theObjectShapes,
+ const bool theListShouldBeCleared = true);
+
/// Fills the map by the feature object and shapes, which should be visuaziled
/// Gets the active widget, obtain the highlighted presentations if it has such and
/// fill map by object and shapes
// Created: 20 August 2015
// Author: Vitaly SMETANNIKOV
+#include <ModelAPI_Tools.h>
+#include <ModelAPI_AttributeString.h>
+
#include "PartSet_OverconstraintListener.h"
+#include <PartSet_Module.h>
+#include <PartSet_SketcherMgr.h>
+#include <PartSet_SketcherReentrantMgr.h>
#include "XGUI_ModuleConnector.h"
#include "XGUI_Workshop.h"
#include "XGUI_Displayer.h"
+#include "XGUI_CustomPrs.h"
#include "SketcherPrs_SymbolPrs.h"
#include "SketchPlugin_SketchEntity.h"
+#include "SketchPlugin_MacroArcReentrantMessage.h"
+#include "SketchPlugin_Sketch.h"
#include "Events_Loop.h"
#include <GeomAPI_IPresentable.h>
#include <ModelAPI_Events.h>
+#include <ModelAPI_EventReentrantMessage.h>
#include <ModuleBase_Tools.h>
#include <QString>
//#define DEBUG_FEATURE_OVERCONSTRAINT_LISTENER
PartSet_OverconstraintListener::PartSet_OverconstraintListener(ModuleBase_IWorkshop* theWorkshop)
-: myWorkshop(theWorkshop)
+: myWorkshop(theWorkshop), myIsActive(false), myIsFullyConstrained(false)
{
Events_Loop* aLoop = Events_Loop::loop();
aLoop->registerListener(this, Events_Loop::eventByName(EVENT_SOLVER_FAILED));
aLoop->registerListener(this, Events_Loop::eventByName(EVENT_SOLVER_REPAIRED));
+
+ aLoop->registerListener(this, Events_Loop::eventByName(EVENT_SKETCH_UNDER_CONSTRAINED));
+ aLoop->registerListener(this, Events_Loop::eventByName(EVENT_SKETCH_FULLY_CONSTRAINED));
+
+ aLoop->registerListener(this, ModelAPI_EventReentrantMessage::eventId());
+ aLoop->registerListener(this, SketchPlugin_MacroArcReentrantMessage::eventId());
}
-bool PartSet_OverconstraintListener::isConflictingObject(const ObjectPtr& theObject)
+void PartSet_OverconstraintListener::setActive(const bool& theActive)
{
- return myConflictingObjects.find(theObject) != myConflictingObjects.end();
+ if (myIsActive == theActive)
+ return;
+
+ myIsActive = theActive;
+ myIsFullyConstrained = false; /// returned to default state, no custom color for it
+
+ if (myIsActive) {
+ PartSet_Module* aModule = module();
+ CompositeFeaturePtr aSketch = aModule->sketchMgr()->activeSketch();
+ if (aSketch.get()) {
+ std::string aDOFMessage = aSketch->string(SketchPlugin_Sketch::SOLVER_DOF())->value();
+ myIsFullyConstrained = QString(aDOFMessage.c_str()).contains("DoF = 0");
+ }
+ }
}
-void PartSet_OverconstraintListener::getConflictingColor(std::vector<int>& theColor)
+void PartSet_OverconstraintListener::getCustomColor(const ObjectPtr& theObject,
+ std::vector<int>& theColor)
{
- Quantity_Color aColor = ModuleBase_Tools::color("Visualization", "sketch_overconstraint_color");
- theColor.push_back(aColor.Red()*255.);
- theColor.push_back(aColor.Green()*255.);
- theColor.push_back(aColor.Blue()*255.);
+ if (!myIsActive)
+ return;
+
+ if (myConflictingObjects.find(theObject) != myConflictingObjects.end()) {
+ theColor = Config_PropManager::color("Visualization", "sketch_overconstraint_color");
+ }
+ if (myIsFullyConstrained) {
+ FeaturePtr aFeature = ModelAPI_Feature::feature(theObject);
+ // only entity features has custom color when sketch is fully constrained
+ if (aFeature.get() && PartSet_SketcherMgr::isEntity(aFeature->getKind())) {
+ PartSet_Module* aModule = module();
+ CompositeFeaturePtr aSketch = aModule->sketchMgr()->activeSketch();
+ // the given object is sub feature of the current sketch(created or edited)
+ if (ModelAPI_Tools::compositeOwner(aFeature) == aSketch)
+ theColor = Config_PropManager::color("Visualization", "sketch_fully_constrained_color");
+ }
+ }
}
void PartSet_OverconstraintListener::processEvent(
const std::shared_ptr<Events_Message>& theMessage)
{
+ if (!myIsActive)
+ return;
+
#ifdef DEBUG_FEATURE_OVERCONSTRAINT_LISTENER
bool isRepaired = theMessage->eventID() == Events_Loop::eventByName(EVENT_SOLVER_REPAIRED);
int aCount = 0;
.arg(aCurrentInfoStr).toStdString().c_str());
#endif
- if (theMessage->eventID() == Events_Loop::eventByName(EVENT_SOLVER_FAILED)) {
+ Events_ID anEventID = theMessage->eventID();
+ if (anEventID == Events_Loop::eventByName(EVENT_SOLVER_FAILED) ||
+ anEventID == Events_Loop::eventByName(EVENT_SOLVER_REPAIRED)) {
std::shared_ptr<ModelAPI_SolverFailedMessage> anErrorMsg =
std::dynamic_pointer_cast<ModelAPI_SolverFailedMessage>(theMessage);
bool anUpdated = false;
if (anErrorMsg.get()) {
const std::set<ObjectPtr>& aConflictingObjects = anErrorMsg->objects();
- anUpdated = appendConflictingObjects(aConflictingObjects);
- }
- else {
- // there is a crash in the solver. All objects are invalid
- //anUpdated = appendConflictingObjects(std::set<ObjectPtr>());
+ if (anEventID == Events_Loop::eventByName(EVENT_SOLVER_FAILED))
+ anUpdated = appendConflictingObjects(aConflictingObjects);
+ else
+ anUpdated = repairConflictingObjects(aConflictingObjects);
}
}
- if (theMessage->eventID() == Events_Loop::eventByName(EVENT_SOLVER_REPAIRED)) {
- std::shared_ptr<ModelAPI_SolverFailedMessage> anErrorMsg =
- std::dynamic_pointer_cast<ModelAPI_SolverFailedMessage>(theMessage);
- bool anUpdated = false;
- if (anErrorMsg.get()) {
- const std::set<ObjectPtr>& aConflictingObjects = anErrorMsg->objects();
- anUpdated = repairConflictingObjects(aConflictingObjects);
- }
- else {
- // there is no repaired objects, do nothing
+ else if (anEventID == Events_Loop::eventByName(EVENT_SKETCH_UNDER_CONSTRAINED) ||
+ anEventID == Events_Loop::eventByName(EVENT_SKETCH_FULLY_CONSTRAINED)) {
+ bool aPrevFullyConstrained = myIsFullyConstrained;
+ myIsFullyConstrained = anEventID == Events_Loop::eventByName(EVENT_SKETCH_FULLY_CONSTRAINED);
+
+ if (aPrevFullyConstrained != myIsFullyConstrained) {
+ std::set<ObjectPtr> aModifiedObjects;
+ PartSet_Module* aModule = dynamic_cast<PartSet_Module*>(myWorkshop->module());
+ CompositeFeaturePtr aSketch = aModule->sketchMgr()->activeSketch();
+ if (aSketch.get()) {
+ for (int i = 0; i < aSketch->numberOfSubs(); i++) {
+ FeaturePtr aFeature = aSketch->subFeature(i);
+ aModifiedObjects.insert(aFeature); // is necessary to redisplay presentations
+ std::list<ResultPtr> aResults = aFeature->results();
+ for (std::list<ResultPtr>::const_iterator aIt = aResults.begin();
+ aIt != aResults.end(); ++aIt) {
+ aModifiedObjects.insert(*aIt);
+ }
+ }
+ redisplayObjects(aModifiedObjects);
+ }
}
}
+ else if (anEventID == ModelAPI_EventReentrantMessage::eventId() ||
+ anEventID == SketchPlugin_MacroArcReentrantMessage::eventId()) {
+ PartSet_Module* aModule = dynamic_cast<PartSet_Module*>(myWorkshop->module());
+ PartSet_SketcherReentrantMgr* aReentrantMgr = aModule->sketchReentranceMgr();
+ aReentrantMgr->setReentrantMessage(theMessage);
+ }
#ifdef DEBUG_FEATURE_OVERCONSTRAINT_LISTENER
aCurrentInfoStr = getObjectsInfo(myConflictingObjects);
const std::set<ObjectPtr>& theConflictingObjects)
{
std::set<ObjectPtr> aModifiedObjects;
- std::vector<int> aColor;
- getConflictingColor(aColor);
// set error state for new objects and append them in the internal map of objects
std::set<ObjectPtr>::const_iterator
aLoop->flush(EVENT_DISP);
}
-XGUI_Workshop* PartSet_OverconstraintListener::workshop() const
+PartSet_Module* PartSet_OverconstraintListener::module() const
{
- XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(myWorkshop);
- return aConnector->workshop();
+ return dynamic_cast<PartSet_Module*>(myWorkshop->module());
}
#ifdef _DEBUG
#include <ModelAPI_Object.h>
class ModuleBase_IWorkshop;
-class XGUI_Workshop;
+class PartSet_Module;
#include <QString>
virtual ~PartSet_OverconstraintListener() {};
- // Set erroneous color for the presentation of object if the object is in the conflicting list
- // \param theObject an object to be settled
- // \param theUpdateViewer a boolean state whether the current viewer should be updated
- //bool customizeObject(ObjectPtr theObject, const bool theUpdateViewer);
+ /// If active state is changed, update fully defined state and sketch sub-entities color
+ /// \param theActive a state
+ void setActive(const bool& theActive);
/// Returns true if the object belongs to internal container of conflicting objects
/// \param theObject an object to be checked
- /// \return boolean result
- bool isConflictingObject(const ObjectPtr& theObject);
-
- /// Returns values of conflicting color
/// \param theColor the output container to be filled in [red, green, blue] values
- void getConflictingColor(std::vector<int>& theColor);
+ /// \return boolean result
+ void getCustomColor(const ObjectPtr& theObject, std::vector<int>& theColor);
/// Redefinition of Events_Listener method
virtual void processEvent(const std::shared_ptr<Events_Message>& theMessage);
void redisplayObjects(const std::set<ObjectPtr>& theObjects);
private:
- /// Returns workshop
- XGUI_Workshop* workshop() const;
+ /// Returns module
+ PartSet_Module* module() const;
#ifdef _DEBUG
/// Unite objects in one string information
#endif
private:
- std::set<ObjectPtr> myConflictingObjects;
ModuleBase_IWorkshop* myWorkshop;
+ bool myIsActive; /// state if sketch is active
+ std::set<ObjectPtr> myConflictingObjects;
+ bool myIsFullyConstrained; /// state if Solver is fully constrained, DOF = 0
};
#endif
if (myModule->sketchReentranceMgr()->processMouseReleased(theWnd, theEvent))
return;
+ // if mouse is pressed when it was over view and at release the mouse is out of view, do nothing
+ if (!myIsMouseOverViewProcessed)
+ return;
+
ModuleBase_IWorkshop* aWorkshop = myModule->workshop();
ModuleBase_IViewer* aViewer = aWorkshop->viewer();
if (!aViewer->canDragByMouse())
}
}
+ // update state of overconstraint listener should be done before sketch features/results
+ // display (as the display will ask custom color from the listener)
+ myModule->overconstraintListener()->setActive(true);
// Display sketcher objects
QStringList anInfo;
Events_ID EVENT_DISP = Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY);
Events_Loop::loop()->flush(aDispEvent);
}
+ myModule->overconstraintListener()->setActive(false);
// restore the module selection modes, which were changed on startSketch
aConnector->activateModuleSelectionModes();
}
#include "ModelAPI_Session.h"
#include "ModelAPI_AttributeString.h"
#include "ModelAPI_AttributeRefAttr.h"
+#include "ModelAPI_EventReentrantMessage.h"
#include "GeomDataAPI_Point2D.h"
#include <SketchPlugin_MacroArc.h>
#include <SketchPlugin_MacroCircle.h>
#include <SketchPlugin_Point.h>
+#include <SketchPlugin_Trim.h>
#include <XGUI_Workshop.h>
#include <XGUI_ModuleConnector.h>
#include <QToolButton>
+//#define DEBUG_RESTART
+
PartSet_SketcherReentrantMgr::PartSet_SketcherReentrantMgr(ModuleBase_IWorkshop* theWorkshop)
: QObject(theWorkshop),
myWorkshop(theWorkshop),
myRestartingMode(RM_None),
myIsFlagsBlocked(false),
myIsInternalEditOperation(false),
- myIsValueChangedBlocked(false),
myInternalActiveWidget(0),
myNoMoreWidgetsAttribute("")
{
ModuleBase_OperationFeature* aCurrentOperation = dynamic_cast<ModuleBase_OperationFeature*>(
myWorkshop->currentOperation());
CompositeFeaturePtr aSketch = module()->sketchMgr()->activeSketch();
- copyReetntrantAttributes(myPreviousFeature, aCurrentOperation->feature(), aSketch);
+ if (myPreviousFeature.get() && myPreviousFeature->data()->isValid()) // it is not removed
+ copyReetntrantAttributes(myPreviousFeature, aCurrentOperation->feature(), aSketch);
}
resetFlags();
}
return isActiveMgr() && myIsInternalEditOperation;
}
-bool PartSet_SketcherReentrantMgr::processMouseReleased(ModuleBase_IViewWindow* theWnd,
- QMouseEvent* theEvent)
+bool PartSet_SketcherReentrantMgr::processMouseReleased(ModuleBase_IViewWindow* theWindow,
+ QMouseEvent* theEvent)
{
bool aProcessed = false;
if (!isActiveMgr())
QList<ModuleBase_ViewerPrsPtr> aPreSelected =
aSelection->getSelected(ModuleBase_ISelection::AllControls);
+ myClickedSketchPoint = PartSet_Tools::getPnt2d(theEvent, theWindow,
+ module()->sketchMgr()->activeSketch());
+ if (!aPreSelected.empty())
+ module()->getGeomSelection(aPreSelected.first(), mySelectedObject, mySelectedAttribute);
+
restartOperation();
+ myClickedSketchPoint = std::shared_ptr<GeomAPI_Pnt2d>();
+ mySelectedObject = ObjectPtr();
+ mySelectedAttribute = AttributePtr();
+
myPreviousFeature = FeaturePtr();
aProcessed = true;
std::shared_ptr<ModuleBase_ViewerPrs> aSelectedPrs;
if (!aPreSelected.empty())
aSelectedPrs = aPreSelected.front();
- aMouseProcessor->setPreSelection(aSelectedPrs, theWnd, theEvent);
- //aPoint2DWdg->mouseReleased(theWnd, theEvent);
+ if (aSelectedPrs.get() && aSelectedPrs->object().get()
+ && !aSelectedPrs->object()->data()->isValid()) {
+ // the selected object was removed diring restart, e.g. presentable macro feature
+ // there are created objects to replace the object depending on created feature kind
+ aSelectedPrs = generatePreSelection();
+ }
+ aMouseProcessor->setPreSelection(aSelectedPrs, theWindow, theEvent);
+ //aPoint2DWdg->mouseReleased(theWindow, theEvent);
//if (!aPreSelected.empty())
// aPoint2DWdg->setPreSelection(ModuleBase_ViewerPrsPtr());
}
ModuleBase_Tools::blockUpdateViewer(false);
}
}
-
return aProcessed;
}
+//******************************************************
+void PartSet_SketcherReentrantMgr::setReentrantPreSelection(
+ const std::shared_ptr<Events_Message>& theMessage)
+{
+ ReentrantMessagePtr aReentrantMessage =
+ std::dynamic_pointer_cast<ModelAPI_EventReentrantMessage>(theMessage);
+ if (!aReentrantMessage.get())
+ return;
+
+ // if feature has already filled the selected object, we should not overwrite it
+ if (!aReentrantMessage->selectedObject().get())
+ aReentrantMessage->setSelectedObject(mySelectedObject);
+
+ aReentrantMessage->setSelectedAttribute(mySelectedAttribute);
+ aReentrantMessage->setClickedPoint(myClickedSketchPoint);
+}
+
void PartSet_SketcherReentrantMgr::onWidgetActivated()
{
if (!isActiveMgr())
void PartSet_SketcherReentrantMgr::onNoMoreWidgets(const std::string& thePreviousAttributeID)
{
+#ifdef DEBUG_RESTART
+ std::cout << "PartSet_SketcherReentrantMgr::onNoMoreWidgets" << std::endl;
+#endif
+
if (!isActiveMgr())
return;
void PartSet_SketcherReentrantMgr::onAfterValuesChangedInPropertyPanel()
{
- // blocked flag in order to avoid circling when storeValue will be applied in
- // this method to cached widget
- if (myIsValueChangedBlocked)
- return;
if (isInternalEditActive()) {
+ ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+ (myWorkshop->currentOperation());
ModuleBase_ModelWidget* aWidget = (ModuleBase_ModelWidget*)sender();
- if (!aWidget->isModifiedInEdit())
+ if (!aWidget->isModifiedInEdit().empty())
restartOperation();
}
}
return !isActiveMgr() || myRestartingMode == RM_None;
}
-bool PartSet_SketcherReentrantMgr::isInternalEditStarted() const
-{
- return myIsInternalEditOperation;
-}
-
bool PartSet_SketcherReentrantMgr::isActiveMgr() const
{
ModuleBase_Operation* aCurrentOperation = myWorkshop->currentOperation();
bool PartSet_SketcherReentrantMgr::startInternalEdit(const std::string& thePreviousAttributeID)
{
+#ifdef DEBUG_RESTART
+ std::cout << "PartSet_SketcherReentrantMgr::startInternalEdit" << std::endl;
+#endif
+
bool isDone = false;
/// this is workaround for ModuleBase_WidgetEditor, used in SALOME mode. Sometimes key enter
/// event comes two times, so we should not start another internal edit operation
void PartSet_SketcherReentrantMgr::restartOperation()
{
+#ifdef DEBUG_RESTART
+ std::cout << "PartSet_SketcherReentrantMgr::restartOperation" << std::endl;
+#endif
+
if (myIsInternalEditOperation) {
ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>(
myWorkshop->currentOperation());
if (aFOperation) {
- // obtain widgets(attributes) which content should be applied to attributes of new feature
- ModuleBase_IPropertyPanel* aPanel = aFOperation->propertyPanel();
- ModuleBase_ModelWidget* anActiveWidget = aPanel->activeWidget();
- const QList<ModuleBase_ModelWidget*>& aWidgets = aPanel->modelWidgets();
- QList<ModuleBase_ModelWidget*> aValueWidgets;
- for (int i = 0, aSize = aWidgets.size(); i < aSize; i++) {
- ModuleBase_ModelWidget* aWidget = aWidgets[i];
- if (!aWidget->isModifiedInEdit()) {
- aValueWidgets.append(aWidget);
- // the widget is cashed to fill feature of new operation by the current widget value
- // we set empty parent to the widget in order to remove it ourselves. Reason: restart
- // operation will clear property panel and delete all widgets. This widget should be
- // removed only after applying value of the widget to new created feature.
- aWidget->setParent(0);
- }
- }
+ ModuleBase_ISelection* aSelection = myWorkshop->selection();
+ QList<ModuleBase_ViewerPrsPtr> aPreSelected =
+ aSelection->getSelected(ModuleBase_ISelection::AllControls);
+
+
+
+ if (myInternalFeature.get())
+ copyReetntrantAttributes(myInternalFeature, aFOperation->feature(),
+ module()->sketchMgr()->activeSketch());
myNoMoreWidgetsAttribute = "";
myIsFlagsBlocked = true;
module()->launchOperation(aFOperation->id());
myIsFlagsBlocked = false;
resetFlags();
+
// we should avoid processing of the signal about no more widgets attributes and
// do this after the restart operaion is finished if it was called
// onNoMoreWidgets depends on myIsFlagsBlocked and fill myNoMoreWidgetsAttribute
onNoMoreWidgets(myNoMoreWidgetsAttribute);
myNoMoreWidgetsAttribute = "";
}
-
- // filling new feature by the previous value of active widget
- // (e.g. circle_type in macro Circle)
- ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>(
- myWorkshop->currentOperation());
- myIsValueChangedBlocked = true; // flag to avoid onAfterValuesChangedInPropertyPanel slot
- for (int i = 0, aSize = aValueWidgets.size(); i < aSize; i++) {
- ModuleBase_ModelWidget* aWidget = aValueWidgets[i];
- aWidget->setEditingMode(false);
- aWidget->setFeature(aFOperation->feature());
- aWidget->storeValue();
- // we must delete this widget
- delete aWidget;
- }
- myIsValueChangedBlocked = false;
}
}
}
CompositeFeaturePtr aSketch = module()->sketchMgr()->activeSketch();
myInternalFeature = aSketch->addFeature(anOperationFeature->getKind());
+#ifdef DEBUG_RESTART
+ std::cout << "PartSet_SketcherReentrantMgr::createInternalFeature: "
+ << myInternalFeature->data()->name() << std::endl;
+#endif
+
bool isFeatureChanged = copyReetntrantAttributes(anOperationFeature, myInternalFeature,
aSketch, false);
XGUI_PropertyPanel* aPropertyPanel = dynamic_cast<XGUI_PropertyPanel*>
void PartSet_SketcherReentrantMgr::deleteInternalFeature()
{
+#ifdef DEBUG_RESTART
+ std::cout << "PartSet_SketcherReentrantMgr::deleteInternalFeature: "
+ << myInternalFeature->data()->name() << std::endl;
+#endif
if (myInternalActiveWidget) {
ModuleBase_WidgetSelector* aWSelector =
dynamic_cast<ModuleBase_WidgetSelector*>(myInternalActiveWidget);
myIsInternalEditOperation = false;
updateAcceptAllAction();
myRestartingMode = RM_None;
+ myReentrantMessage = std::shared_ptr<Events_Message>();
}
}
bool PartSet_SketcherReentrantMgr::copyReetntrantAttributes(const FeaturePtr& theSourceFeature,
const FeaturePtr& theNewFeature,
const CompositeFeaturePtr& theSketch,
- const bool isTemporary)
+ const bool /*isTemporary*/)
{
bool aChanged = false;
if (!theSourceFeature.get() || !theSourceFeature->data().get() ||
!theSourceFeature->data()->isValid())
return aChanged;
+#ifdef DEBUG_RESTART
+ std::cout << "PartSet_SketcherReentrantMgr::copyReetntrantAttributes from '"
+ << theSourceFeature->data()->name() << "' to '" << theNewFeature->data()->name()
+ << "'" << std::endl;
+#endif
+
std::string aFeatureKind = theSourceFeature->getKind();
- if (aFeatureKind == SketchPlugin_Line::ID()) {
+ /*if (aFeatureKind == SketchPlugin_Line::ID()) {
// Initialize new line with first point equal to end of previous
std::shared_ptr<ModelAPI_Data> aSFData = theSourceFeature->data();
std::shared_ptr<GeomDataAPI_Point2D> aSPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
aSFData->attribute(SketchPlugin_Line::END_ID()));
aNPoint->setValue(aSPoint->x(), aSPoint->y());
}
- else if (aFeatureKind == SketchPlugin_MacroCircle::ID()) {
+ else*/ if (aFeatureKind == SketchPlugin_MacroCircle::ID()) {
// set circle type
- std::string aTypeAttributeId = SketchPlugin_MacroCircle::CIRCLE_TYPE();
+ /*std::string aTypeAttributeId = SketchPlugin_MacroCircle::CIRCLE_TYPE();
AttributeStringPtr aSourceFeatureTypeAttr = theSourceFeature->data()->string(aTypeAttributeId);
AttributeStringPtr aNewFeatureTypeAttr = theNewFeature->data()->string(aTypeAttributeId);
- aNewFeatureTypeAttr->setValue(aSourceFeatureTypeAttr->value());
+ if (aNewFeatureTypeAttr->value() != aTypeAttributeId) // do nothing if there is no changes
+ aNewFeatureTypeAttr->setValue(aSourceFeatureTypeAttr->value());
//ModuleBase_Tools::flushUpdated(theNewFeature);
- aChanged = true;
+ aChanged = true;*/
}
else if (aFeatureKind == SketchPlugin_MacroArc::ID()) {
// set arc type
std::string aTypeAttributeId = SketchPlugin_MacroArc::ARC_TYPE();
AttributeStringPtr aSourceFeatureTypeAttr = theSourceFeature->data()->string(aTypeAttributeId);
AttributeStringPtr aNewFeatureTypeAttr = theNewFeature->data()->string(aTypeAttributeId);
- aNewFeatureTypeAttr->setValue(aSourceFeatureTypeAttr->value());
-
+ if (aNewFeatureTypeAttr->value() != aTypeAttributeId) // do nothing if there is no changes
+ aNewFeatureTypeAttr->setValue(aSourceFeatureTypeAttr->value());
//// if the arc is tangent, set coincidence to end point of the previous arc
//std::string anArcType = aSourceFeatureTypeAttr->value();
//if (anArcType == SketchPlugin_Arc::ARC_TYPE_TANGENT()) {
//ModuleBase_Tools::flushUpdated(theNewFeature);
aChanged = true;
}
+ else if (aFeatureKind == SketchPlugin_Trim::ID()) {
+ /*std::shared_ptr<ModelAPI_AttributeReference> aRefSelectedAttr =
+ std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
+ theSourceFeature->data()->attribute(SketchPlugin_Trim::SELECTED_OBJECT()));
+ std::shared_ptr<ModelAPI_AttributeReference> aNRefSelectedAttr =
+ std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
+ theNewFeature->data()->attribute(SketchPlugin_Trim::SELECTED_OBJECT()));
+ aNRefSelectedAttr->setValue(aRefSelectedAttr->value());*/
+
+ std::shared_ptr<ModelAPI_AttributeReference> aRefPreviewAttr =
+ std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
+ theSourceFeature->data()->attribute(SketchPlugin_Trim::PREVIEW_OBJECT()));
+ std::shared_ptr<ModelAPI_AttributeReference> aNRefPreviewAttr =
+ std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
+ theNewFeature->data()->attribute(SketchPlugin_Trim::PREVIEW_OBJECT()));
+ aNRefPreviewAttr->setValue(aRefPreviewAttr->value());
+
+ /*std::shared_ptr<GeomDataAPI_Point2D> aPointSelectedAttr =
+ std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ theSourceFeature->data()->attribute(SketchPlugin_Trim::SELECTED_POINT()));
+ std::shared_ptr<GeomDataAPI_Point2D> aNPointSelectedAttr =
+ std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ theNewFeature->data()->attribute(SketchPlugin_Trim::SELECTED_POINT()));
+ aNPointSelectedAttr->setValue(aPointSelectedAttr->x(), aPointSelectedAttr->y());
+ */
+ std::shared_ptr<GeomDataAPI_Point2D> aPointPreviewAttr =
+ std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ theSourceFeature->data()->attribute(SketchPlugin_Trim::PREVIEW_POINT()));
+ std::shared_ptr<GeomDataAPI_Point2D> aNPointPreviewAttr =
+ std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ theNewFeature->data()->attribute(SketchPlugin_Trim::PREVIEW_POINT()));
+ aNPointPreviewAttr->setValue(aPointPreviewAttr->x(), aPointPreviewAttr->y());
+
+ aChanged = true;
+ }
return aChanged;
}
return aTangentArc;
}
+std::shared_ptr<ModuleBase_ViewerPrs> PartSet_SketcherReentrantMgr::generatePreSelection()
+{
+ std::shared_ptr<ModuleBase_ViewerPrs> aPrs;
+
+ return aPrs;
+}
+
void PartSet_SketcherReentrantMgr::updateAcceptAllAction()
{
CompositeFeaturePtr aSketch = module()->sketchMgr()->activeSketch();
#include <ModelAPI_Feature.h>
#include <string>
+#include <memory>
#include <QObject>
class XGUI_Workshop;
class PartSet_Module;
+class ModuleBase_ViewerPrs;
+class Events_Message;
+class ModelAPI_Attribute;
+class GeomAPI_Pnt2d;
/// \ingroup PartSet_SketcherReentrantMgr
/// It provides reentrant create operations in sketch, that is when all inputs are valid,
/// Returns false if the reentrant mode of the operation is not empty.
bool canBeCommittedByPreselection();
- /// returns true if an internal edit operation is started
- /// \return boolean value
- bool isInternalEditStarted() const;
+ /// Fills reentrant message during restarting operation
+ /// \param theMessage reentrant message
+ void setReentrantMessage(const std::shared_ptr<Events_Message>& theMessage)
+ { myReentrantMessage = theMessage; }
+
+ /// Returnss reentrant message
+ std::shared_ptr<Events_Message> reentrantMessage() const { return myReentrantMessage; }
+
+ /// Put current selection into reentrant message
+ /// \param theMessage a message of reentrant operation
+ void setReentrantPreSelection(const std::shared_ptr<Events_Message>& theMessage);
private slots:
/// SLOT, that is called by a widget activating in the property panel
bool isTangentArc(ModuleBase_Operation* theOperation,
const std::shared_ptr<ModelAPI_CompositeFeature>& /*theSketch*/) const;
+ /// Creates selection instance by the current feature and created by restart objects
+ /// \returns viewer selection presentation
+ std::shared_ptr<ModuleBase_ViewerPrs> generatePreSelection();
+
/// Accept All action is enabled if an internal edit is started.
/// It updates the state of the button
void updateAcceptAllAction();
RestartingMode myRestartingMode; /// automatical restarting mode flag
bool myIsFlagsBlocked; /// true when reset of flags should not be perfromed
bool myIsInternalEditOperation; /// true when the 'internal' edit is started
- bool myIsValueChangedBlocked; /// blocked flag to avoid circling by value changed
FeaturePtr myPreviousFeature; /// feature of the previous operation, which is restarted
FeaturePtr myInternalFeature;
QWidget* myInternalWidget;
ModuleBase_ModelWidget* myInternalActiveWidget;
std::string myNoMoreWidgetsAttribute;
+
+ std::shared_ptr<Events_Message> myReentrantMessage; /// message obtained by operation restart
+ ObjectPtr mySelectedObject; /// cashed selected object
+ std::shared_ptr<ModelAPI_Attribute> mySelectedAttribute; /// cashed selected attribute
+ std::shared_ptr<GeomAPI_Pnt2d> myClickedSketchPoint; /// cashed clicked point
};
#endif
#include <ModelAPI_Events.h>
#include <ModelAPI_Validator.h>
+#include <ModuleBase_IViewWindow.h>
+
#include <ModelGeomAlgo_Point2D.h>
#include <Events_Loop.h>
#include <StdSelect_BRepOwner.hxx>
#include <SelectMgr_IndexedMapOfOwner.hxx>
+#include <QMouseEvent>
+
#ifdef _DEBUG
#include <QDebug>
#endif
return std::shared_ptr<GeomAPI_Pnt2d>();
}
+std::shared_ptr<GeomAPI_Pnt2d> PartSet_Tools::getPnt2d(QMouseEvent* theEvent,
+ ModuleBase_IViewWindow* theWindow,
+ const FeaturePtr& theSketch)
+{
+ gp_Pnt aPnt = PartSet_Tools::convertClickToPoint(theEvent->pos(), theWindow->v3dView());
+ double aX, anY;
+ Handle(V3d_View) aView = theWindow->v3dView();
+ PartSet_Tools::convertTo2D(aPnt, theSketch, aView, aX, anY);
+
+ return std::shared_ptr<GeomAPI_Pnt2d>(new GeomAPI_Pnt2d(aX, anY));
+}
+
FeaturePtr findFirstCoincidenceByData(const DataPtr& theData,
std::shared_ptr<GeomAPI_Pnt2d> thePoint)
{
#include <memory>
class V3d_View;
+class ModuleBase_IViewWindow;
class ModuleBase_ViewerPrs;
class ModuleBase_IWorkshop;
class GeomDataAPI_Point2D;
class GeomAPI_Vertex;
class ModelAPI_Result;
+class QMouseEvent;
+
/*!
* \class PartSet_Tools
* \ingroup Modules
static std::shared_ptr<GeomAPI_Pnt2d> getPoint(std::shared_ptr<ModelAPI_Feature>& theFeature,
const std::string& theAttribute);
+ /**
+ * Convertes parameters into a geom point
+ * \theEvent a Qt event to find mouse position
+ * \param theWindow view window to define eye of view
+ * \param theSketch to convert 3D point coordinates into coorditates of the sketch plane
+ */
+ static std::shared_ptr<GeomAPI_Pnt2d> getPnt2d(QMouseEvent* theEvent,
+ ModuleBase_IViewWindow* theWindow,
+ const FeaturePtr& theSketch);
+
/**
* Gets all references to the feature, take coincidence constraint features, get point 2d attributes
* and compare the point value to be equal with the given. Returns the first feature, which has
if (theSelectedPrs.get() && theSelectedPrs->object().get())
anObject = theSelectedPrs->object();
- gp_Pnt aPnt = PartSet_Tools::convertClickToPoint(theEvent->pos(), theWindow->v3dView());
- double aX, anY;
- Handle(V3d_View) aView = theWindow->v3dView();
- PartSet_Tools::convertTo2D(aPnt, mySketch, aView, aX, anY);
+ if (!anObject.get())
+ return aFilled;
std::shared_ptr<ModelAPI_AttributeReference> aRef =
std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
std::shared_ptr<GeomDataAPI_Point2D> anAttributePoint =
std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
feature()->data()->attribute(SketchPlugin_Trim::PREVIEW_POINT()));
- anAttributePoint->setValue(aX, anY);
+ std::shared_ptr<GeomAPI_Pnt2d> aPoint = PartSet_Tools::getPnt2d(theEvent, theWindow, mySketch);
+ anAttributePoint->setValue(aPoint);
// redisplay AIS presentation in viewer
#ifndef HIGHLIGHT_STAYS_PROBLEM
// an attempt to clear highlighted item in the viewer: but of OCCT
{
PartSet_Module* aModule = dynamic_cast<PartSet_Module*>(myWorkshop->module());
- if (isEditingMode() || aModule->sketchReentranceMgr()->isInternalEditStarted())
+ if (isEditingMode() || aModule->sketchReentranceMgr()->isInternalEditActive())
return;
gp_Pnt aPoint = PartSet_Tools::convertClickToPoint(theEvent->pos(), theWindow->v3dView());
TestFeatures.py
TestFeaturesExtrusion.py
#TestFeaturesRevolution.py
-
+
TestPrimitivesBox.py
TestMakeBrick1.py
TestMakeBrick2.py
TestPlatine.py
+
+ Test2044.py
)
--- /dev/null
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(-184.375, -81.25, -71.87500000000006, 206.2500000000001)
+SketchLine_2 = Sketch_1.addLine(-71.87500000000006, 206.2500000000001, 281.2500000000001, 178.125)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(281.2500000000001, 178.125, 184.3750000000001, -109.375)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchLine_4 = Sketch_1.addLine(184.3750000000001, -109.375, -184.375, -81.25)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchLine_4.endPoint())
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("WIRE", "Sketch_1/Wire-SketchLine_1r-SketchLine_2r-SketchLine_3r-SketchLine_4r")], model.selection("EDGE", "PartSet/OZ"), 50, 0)
+model.do()
+Extrusion_1.setDirection(model.selection("EDGE", "OX"))
+model.do()
+model.end()
+
+assert (len(Extrusion_1.feature().error()) != 0)
mirrored_objects = mirror.mirroredObjects()
mirrored_circle = mirrored_objects.object(0)
circle_feature = ModelAPI_Feature.feature(mirrored_circle)
- center = geomDataAPI_Point2D(circle_feature.attribute("CircleCenter"))
+ center = geomDataAPI_Point2D(circle_feature.attribute("circle_center"))
self.assertEqual(center.x(), -30)
# dir(mirrored_circle)
- # center = geomDataAPI_Point2D(mirrored_circle.data().attribute("CircleCenter"))
+ # center = geomDataAPI_Point2D(mirrored_circle.data().attribute("circle_center"))
# self.assertEqual(center.x(), -30, msg="%s"%(dir(mirrored_circle)))
# self.assertTrue(False, msg="%s" % (dir(mirrored_circle)))
def setUp(self):
SketcherTestCase.setUp(self)
self.line = self.sketch.addLine(0, 0, 0, 1)
- self.arc = self.sketch.addArc(0, 1, 0, 0, 1, 1)
+ self.arc = self.sketch.addArc(0, 1, 0, 0, 1, 1, False)
self.sketch.setCoincident(
- self.line.endPoint(), self.arc.startPoint()
+ self.line.startPoint(), self.arc.startPoint()
)
def test_set_tangent(self):
"""
from SketchAPI import addSketch
-from tools import addPolyline, addPolygon, dof
+from tools import *
# Copyright (C) 2014-20xx CEA/DEN, EDF R&D
import ModelHighAPI
+import GeomDataAPI
def addPolyline(sketch, *coords):
"""Add a poly-line to sketch.
aSketch = sketch
if issubclass(type(aSketch), ModelHighAPI.ModelHighAPI_Interface):
aSketch = sketch.feature()
- return int(filter(str.isdigit, aSketch.string("SolverDOF").value()))
\ No newline at end of file
+ return int(filter(str.isdigit, aSketch.string("SolverDOF").value()))
+
+def distancePointPoint(thePoint1, thePoint2):
+ aGeomPnt1 = thePoint1
+ aGeomPnt2 = thePoint2
+ if issubclass(type(thePoint1), GeomDataAPI.GeomDataAPI_Point2D):
+ aGeomPnt1 = thePoint1.pnt()
+ if issubclass(type(thePoint2), GeomDataAPI.GeomDataAPI_Point2D):
+ aGeomPnt2 = thePoint2.pnt()
+ return aGeomPnt1.distance(aGeomPnt2)
+
+def lastSubFeature(theSketch, theKind):
+ """
+ obtains last feature of given kind from the sketch
+ """
+ for anIndex in range(theSketch.numberOfSubs() - 1, -1, -1):
+ aSub = theSketch.subFeature(anIndex)
+ if (aSub.getKind() == theKind):
+ return aSub
from GeomAlgoAPI import *
from GeomAPI import *
+from GeomDataAPI import *
from ModelAPI import ModelAPI_Feature
import math
+from salome.shaper.model import sketcher
+TOLERANCE = 1.e-7
aShapeTypes = {
GeomAPI_Shape.SOLID: "GeomAPI_Shape.SOLID",
assert (aNbResultSubShapes == anExpectedNbSubShapes), "Number of sub-shapes of type {} for result[{}]: {}. Expected: {}.".format(aShapeTypes[theShapeType], anIndex, aNbResultSubShapes, anExpectedNbSubShapes)
-def testResultsVolumes(theFeature, theExpectedResultsVolumes, theNbSignificantDigits = 10):
+def testResultsVolumes(theFeature, theExpectedResultsVolumes, theNbSignificantDigits = 7):
""" Tests results volumes.
:param theFeature: feature to test.
:param theExpectedResultsVolumes: list of results volumes. Size of list should be equal to len(theFeature.results()).
"""
+ aTolerance = 10**(-theNbSignificantDigits)
aNbResults = len(theFeature.results())
aListSize = len(theExpectedResultsVolumes)
assert (aNbResults == aListSize), "Number of results: {} not equal to list size: {}.".format(aNbResults, aListSize)
aResultVolumeStr = "{:0.27f}".format(aResultVolume).lstrip("0").lstrip(".").lstrip("0")
anExpectedResultVolume = theExpectedResultsVolumes[anIndex]
anExpectedResultVolumeStr = "{:0.27f}".format(anExpectedResultVolume).lstrip("0").lstrip(".").lstrip("0")
- assert (aResultVolumeStr[:theNbSignificantDigits] == anExpectedResultVolumeStr[:theNbSignificantDigits]), "Volume of result[{}]: {:0.27f}. Expected: {:0.27f}. The first {} significant digits not equal.".format(anIndex, aResultVolume, anExpectedResultVolume, theNbSignificantDigits)
+ assert math.fabs(aResultVolume - anExpectedResultVolume) < aTolerance * anExpectedResultVolume, "Volume of result[{}]: {:0.27f}. Expected: {:0.27f}. The first {} significant digits not equal.".format(anIndex, aResultVolume, anExpectedResultVolume, theNbSignificantDigits)
def testHaveNamingFaces(theFeature, theModel, thePartDoc) :
""" Tests if all faces of result have a name
if aFeature is not None and aFeature.getKind() == theKindOfSub:
count += 1
assert (count == theExpectedCount), "Number of sub-features of type {}: {}, expected {}".format(theKindOfSub, count, theExpectedCount)
+
+def assertSketchArc(theArcFeature):
+ """ Tests whether the arc is correctly defined
+ """
+ aCenterPnt = geomDataAPI_Point2D(theArcFeature.attribute("center_point"))
+ aStartPnt = geomDataAPI_Point2D(theArcFeature.attribute("start_point"))
+ aEndPnt = geomDataAPI_Point2D(theArcFeature.attribute("end_point"))
+ aRadius = theArcFeature.real("radius")
+ aDistCS = sketcher.tools.distancePointPoint(aCenterPnt, aStartPnt)
+ aDistCE = sketcher.tools.distancePointPoint(aCenterPnt, aEndPnt)
+ assert math.fabs(aDistCS - aDistCE) < TOLERANCE, "Wrong arc: center-start distance {}, center-end distance {}".format(aDistCS, aDistCE)
+ assert math.fabs(aRadius.value() -aDistCS) < TOLERANCE, "Wrong arc: radius is {0}, expected {1}".format(aRadius.value(), aDistCS)
SketchPlugin_IntersectionPoint.h
SketchPlugin_Line.h
SketchPlugin_MacroArc.h
+ SketchPlugin_MacroArcReentrantMessage.h
SketchPlugin_MacroCircle.h
SketchPlugin_MultiRotation.h
SketchPlugin_MultiTranslation.h
INSTALL(FILES ${TEXT_RESOURCES} DESTINATION ${SHAPER_INSTALL_XML_RESOURCES})
ADD_UNIT_TESTS(TestSketchPointLine.py
- TestCreateArc.py
+ TestCreateArcByCenterStartEnd.py
+ TestCreateArcByThreePoints.py
+ TestCreateArcByTangentEdge.py
+ TestCreateArcChangeType.py
TestCreateCircleByCenterAndPassed.py
TestCreateCircleByThreePoints.py
TestCreateCircleChangeType.py
TestConstraintVertical.py
TestConstraintEqual.py
TestConstraintTangent.py
- TestConstraintMirror.py
TestConstraintAngle.py
TestConstraintMiddlePoint.py
+ TestMirror.py
TestMultiRotation.py
TestMultiTranslation.py
TestFillet.py
GeomAlgoAPI_EdgeBuilder::lineCircleArc(aCenter, anEnd, aStart, aNormal)
: GeomAlgoAPI_EdgeBuilder::lineCircleArc(aCenter, aStart, anEnd, aNormal);
+ if (myParamBefore == 0) { // parameter has not been calculate yet
+ std::shared_ptr<GeomAPI_Circ2d> aCircleForArc(
+ new GeomAPI_Circ2d(aCenterAttr->pnt(), aStartAttr->pnt()));
+ aCircleForArc->parameter(anEndAttr->pnt(), paramTolerance, myParamBefore);
+ }
+
std::shared_ptr<ModelAPI_ResultConstruction> aResult = document()->createConstruction(data(), 1);
aResult->setShape(anArcShape);
aResult->setIsInHistory(false);
aCirc->parameter(anEdge->firstPoint(), paramTolerance, aStartParam);
aCirc->parameter(aMinPnt, paramTolerance, aMidParam);
aCirc->parameter(anEdge->lastPoint(), paramTolerance, anEndParam);
+
+ // adjust period
+ anEndParam -= aStartParam;
+ aMidParam -= aStartParam;
+ if (anEndParam < 0.0)
+ anEndParam += 2.0 * PI;
+ if (aMidParam < 0.0)
+ aMidParam += 2.0 * PI;
+
aWasBlocked = data()->blockSendAttributeUpdated(true);
- if(aStartParam < aMidParam && aMidParam < anEndParam) {
+ if(aMidParam < anEndParam) {
setReversed(false);
} else {
setReversed(true);
return;
std::shared_ptr<GeomAPI_Circ2d> aCircleForArc(new GeomAPI_Circ2d(aCenter, aStart));
- bool aWasBlocked = data()->blockSendAttributeUpdated(true);
- // The Arc end point is projected
- // on the circle formed by center and start points
+ // Do not recalculate REVERSED flag if the arc is not consistent
std::shared_ptr<GeomAPI_Pnt2d> aProjection = aCircleForArc->project(anEnd);
- if (aProjection && anEnd->distance(aProjection) > tolerance) {
- anEndAttr->setValue(aProjection);
- anEnd = aProjection;
- }
- data()->blockSendAttributeUpdated(aWasBlocked, false);
-
- double aParameterNew = 0.0;
- if(aCircleForArc->parameter(anEnd, paramTolerance, aParameterNew)) {
- bool aWasBlocked = data()->blockSendAttributeUpdated(true);
- if(myParamBefore <= PI / 2.0 && aParameterNew >= PI * 1.5) {
- if(!boolean(REVERSED_ID())->value()) {
- boolean(REVERSED_ID())->setValue(true);
- }
- } else if(myParamBefore >= PI * 1.5 && aParameterNew <= PI / 2.0) {
- if(boolean(REVERSED_ID())->value()) {
- boolean(REVERSED_ID())->setValue(false);
+ if (aProjection && anEnd->distance(aProjection) <= tolerance) {
+ double aParameterNew = 0.0;
+ if(aCircleForArc->parameter(anEnd, paramTolerance, aParameterNew)) {
+ bool aWasBlocked = data()->blockSendAttributeUpdated(true);
+ if(myParamBefore <= PI / 2.0 && aParameterNew >= PI * 1.5) {
+ if(!boolean(REVERSED_ID())->value()) {
+ boolean(REVERSED_ID())->setValue(true);
+ }
+ } else if(myParamBefore >= PI * 1.5 && aParameterNew <= PI / 2.0) {
+ if(boolean(REVERSED_ID())->value()) {
+ boolean(REVERSED_ID())->setValue(false);
+ }
}
+ data()->blockSendAttributeUpdated(aWasBlocked, false);
}
- data()->blockSendAttributeUpdated(aWasBlocked, false);
+ myParamBefore = aParameterNew;
}
- myParamBefore = aParameterNew;
}
double aRadius = 0;
#include <SketchPlugin_Arc.h>
#include <SketchPlugin_Circle.h>
+#include <ModelAPI_Events.h>
#include <ModelGeomAlgo_Point2D.h>
#include <GeomDataAPI_Point2D.h>
#include <SketcherPrs_Factory.h>
+#include <Events_Loop.h>
+
SketchPlugin_ConstraintCoincidence::SketchPlugin_ConstraintCoincidence()
{
}
SketchPlugin_Point::ID(), SketchPlugin_Point::COORD_ID());
return aPoint;
}
+
+void SketchPlugin_ConstraintCoincidence::createCoincidenceFeature(SketchPlugin_Sketch* theSketch,
+ const std::shared_ptr<GeomDataAPI_Point2D>& thePoint1,
+ const std::shared_ptr<GeomDataAPI_Point2D>& thePoint2)
+{
+ FeaturePtr aFeature;
+ if (theSketch) {
+ aFeature = theSketch->addFeature(SketchPlugin_ConstraintCoincidence::ID());
+ } else {
+ std::shared_ptr<ModelAPI_Document> aDoc = theSketch->document();
+ aFeature = aDoc->addFeature(SketchPlugin_ConstraintCoincidence::ID());
+ }
+
+ std::shared_ptr<ModelAPI_Data> aData = aFeature->data();
+
+ std::shared_ptr<ModelAPI_AttributeRefAttr> aRef1 = std::dynamic_pointer_cast<
+ ModelAPI_AttributeRefAttr>(aData->attribute(SketchPlugin_Constraint::ENTITY_A()));
+ aRef1->setAttr(thePoint1);
+
+ std::shared_ptr<ModelAPI_AttributeRefAttr> aRef2 = std::dynamic_pointer_cast<
+ ModelAPI_AttributeRefAttr>(aData->attribute(SketchPlugin_Constraint::ENTITY_B()));
+ aRef2->setAttr(thePoint2);
+
+ // we need to flush created signal in order to coincidence is processed by solver
+ Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED));
+}
static FeaturePtr findCoincidenceFeature(const FeaturePtr& theFeature1,
const FeaturePtr& theFeature2);
+ /// Creates a constraint on two points
+ /// \param theSketch a sketch feature
+ /// \param thePoint1 the first point
+ /// \param thePoint2 the second point
+ static void createCoincidenceFeature(SketchPlugin_Sketch* theSketch,
+ const std::shared_ptr<GeomDataAPI_Point2D>& thePoint1,
+ const std::shared_ptr<GeomDataAPI_Point2D>& thePoint2);
+
/// Returns point of coincidence feature
/// \param theFeature a coincidence feature
/// \return point 2d attribute. Coincidence always has at least one point 2d attribute
#include <ModelAPI_Tools.h>
#include <ModelAPI_Validator.h>
+#include <GeomAlgoAPI_Circ2dBuilder.h>
#include <GeomAlgoAPI_EdgeBuilder.h>
#include <GeomAPI_Circ2d.h>
const double tolerance = 1.e-7;
const double paramTolerance = 1.e-4;
+const double PI = 3.141592653589793238463;
/// \brief Attract specified point on theNewArc to the attribute of theFeature
static void recalculateAttributes(FeaturePtr theNewArc, const std::string& theNewArcAttribute,
FeaturePtr theFeature, const std::string& theFeatureAttribute);
+
+/// \brief Calculate radius of a fillet.
+/// It should not be greater than 1/3 of shortest edge length.
+static double calculateFilletRadius(FeaturePtr theFilletFeatures[2]);
+
/// \brief Calculates center of fillet arc and coordinates of tangency points
-static void calculateFilletCenter(FeaturePtr theFeatureA, FeaturePtr theFeatureB,
- double theRadius, bool theNotInversed[2],
+static void calculateFilletCenter(FeaturePtr theFilletFeatures[2],
+ double theFilletRadius,
+ const std::shared_ptr<GeomAPI_Ax3>& theSketchPlane,
std::shared_ptr<GeomAPI_XY>& theCenter,
std::shared_ptr<GeomAPI_XY>& theTangentA,
std::shared_ptr<GeomAPI_XY>& theTangentB);
-/// Get point on 1/3 length of edge from fillet point
-static void getPointOnEdge(const FeaturePtr theFeature,
- const std::shared_ptr<GeomAPI_Pnt2d> theFilletPoint,
- std::shared_ptr<GeomAPI_Pnt2d>& thePoint);
-
-/// Get distance from point to feature
-static double getProjectionDistance(const FeaturePtr theFeature,
- const std::shared_ptr<GeomAPI_Pnt2d> thePoint);
-
/// Get coincide edges for fillet
static std::set<FeaturePtr> getCoincides(const FeaturePtr& theConstraintCoincidence);
return false;
}
- // Getting points located at 1/3 of edge length from fillet point.
std::shared_ptr<GeomAPI_Pnt2d> aFilletPnt2d = aFilletPoint2D->pnt();
- std::shared_ptr<GeomAPI_Pnt2d> aPnt1, aPnt2;
- getPointOnEdge(myBaseFeatures[0], aFilletPnt2d, aPnt1);
- getPointOnEdge(myBaseFeatures[1], aFilletPnt2d, aPnt2);
-
- /// Getting distances.
- double aDistance1 = getProjectionDistance(myBaseFeatures[1], aPnt1);
- double aDistance2 = getProjectionDistance(myBaseFeatures[0], aPnt2);
-
- // Calculate radius value for fillet.
- double aRadius = aDistance1 < aDistance2 ? aDistance1 / 2.0 : aDistance2 / 2.0;
+ double aRadius = calculateFilletRadius(myBaseFeatures);
// Calculate arc attributes.
static const int aNbFeatures = 2;
}
}
- calculateFilletCenter(myBaseFeatures[0], myBaseFeatures[1], aRadius,
- myIsNotInversed, myCenterXY, myTangentXY1, myTangentXY2);
+ std::shared_ptr<GeomAPI_Ax3> aSketchPlane = SketchPlugin_Sketch::plane(sketch());
+ calculateFilletCenter(myBaseFeatures, aRadius, aSketchPlane,
+ myCenterXY, myTangentXY1, myTangentXY2);
// Tangent directions of the features in coincident point.
std::shared_ptr<GeomAPI_Dir2d> aTangentDir[aNbFeatures];
theFeature->attribute(theFeatureAttribute))->setValue(anArcPoint->x(), anArcPoint->y());
}
-/// \brief Find intersections of lines shifted along normal direction
-void possibleFilletCenterLineLine(
- std::shared_ptr<GeomAPI_XY> thePointA, std::shared_ptr<GeomAPI_Dir2d> theDirA,
- std::shared_ptr<GeomAPI_XY> thePointB, std::shared_ptr<GeomAPI_Dir2d> theDirB,
- double theRadius, std::list< std::shared_ptr<GeomAPI_XY> >& theCenters)
+static std::shared_ptr<GeomAPI_Pnt2d> toPoint(const AttributePtr& theAttribute)
{
- std::shared_ptr<GeomAPI_Dir2d> aDirAT(new GeomAPI_Dir2d(-theDirA->y(), theDirA->x()));
- std::shared_ptr<GeomAPI_Dir2d> aDirBT(new GeomAPI_Dir2d(-theDirB->y(), theDirB->x()));
- std::shared_ptr<GeomAPI_XY> aPntA, aPntB;
- double aDet = theDirA->cross(theDirB);
- for (double aStepA = -1.0; aStepA <= 1.0; aStepA += 2.0) {
- aPntA = thePointA->added(aDirAT->xy()->multiplied(aStepA * theRadius));
- for (double aStepB = -1.0; aStepB <= 1.0; aStepB += 2.0) {
- aPntB = thePointB->added(aDirBT->xy()->multiplied(aStepB * theRadius));
- double aVX = aDirAT->xy()->dot(aPntA);
- double aVY = aDirBT->xy()->dot(aPntB);
- std::shared_ptr<GeomAPI_XY> aPoint(new GeomAPI_XY(
- (theDirB->x() * aVX - theDirA->x() * aVY) / aDet,
- (theDirB->y() * aVX - theDirA->y() * aVY) / aDet));
- theCenters.push_back(aPoint);
- }
- }
+ std::shared_ptr<GeomAPI_Pnt2d> aPoint;
+ AttributePoint2DPtr aPointAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(theAttribute);
+ if (aPointAttr)
+ aPoint = aPointAttr->pnt();
+ return aPoint;
}
-/// \brief Find intersections of line shifted along normal direction in both sides
-/// and a circle with extended radius
-void possibleFilletCenterLineArc(
- std::shared_ptr<GeomAPI_XY> theStartLine, std::shared_ptr<GeomAPI_Dir2d> theDirLine,
- std::shared_ptr<GeomAPI_XY> theCenterArc, double theRadiusArc,
- double theRadius, std::list< std::shared_ptr<GeomAPI_XY> >& theCenters)
+static std::shared_ptr<GeomAPI_Lin2d> toLine(const FeaturePtr& theFeature)
{
- std::shared_ptr<GeomAPI_Dir2d> aDirT(new GeomAPI_Dir2d(-theDirLine->y(), theDirLine->x()));
- std::shared_ptr<GeomAPI_XY> aPnt;
- double aDirNorm2 = theDirLine->dot(theDirLine);
- double aRad = 0.0;
- double aDirX = theDirLine->x();
- double aDirX2 = theDirLine->x() * theDirLine->x();
- double aDirY2 = theDirLine->y() * theDirLine->y();
- double aDirXY = theDirLine->x() * theDirLine->y();
- for (double aStepA = -1.0; aStepA <= 1.0; aStepA += 2.0) {
- aPnt = theStartLine->added(aDirT->xy()->multiplied(aStepA * theRadius));
- double aCoeff = aDirT->xy()->dot(aPnt->decreased(theCenterArc));
- double aCoeff2 = aCoeff * aCoeff;
- for (double aStepB = -1.0; aStepB <= 1.0; aStepB += 2.0) {
- aRad = theRadiusArc + aStepB * theRadius;
- double aD = aRad * aRad * aDirNorm2 - aCoeff2;
- if (aD < 0.0)
- continue;
- double aDs = sqrt(aD);
- double x1 = theCenterArc->x() + (aCoeff * aDirT->x() - aDirT->y() * aDs) / aDirNorm2;
- double x2 = theCenterArc->x() + (aCoeff * aDirT->x() + aDirT->y() * aDs) / aDirNorm2;
- double y1 = (aDirX2 * aPnt->y() + aDirY2 * theCenterArc->y() -
- aDirXY * (aPnt->x() - theCenterArc->x()) - theDirLine->y() * aDs) / aDirNorm2;
- double y2 = (aDirX2 * aPnt->y() + aDirY2 * theCenterArc->y() -
- aDirXY * (aPnt->x() - theCenterArc->x()) + theDirLine->y() * aDs) / aDirNorm2;
-
- std::shared_ptr<GeomAPI_XY> aPoint1(new GeomAPI_XY(x1, y1));
- theCenters.push_back(aPoint1);
- std::shared_ptr<GeomAPI_XY> aPoint2(new GeomAPI_XY(x2, y2));
- theCenters.push_back(aPoint2);
- }
+ std::shared_ptr<GeomAPI_Lin2d> aLine;
+ if (theFeature->getKind() == SketchPlugin_Line::ID()) {
+ std::shared_ptr<GeomAPI_Pnt2d> aStart =
+ toPoint( theFeature->attribute(SketchPlugin_Line::START_ID()) );
+ std::shared_ptr<GeomAPI_Pnt2d> aEnd =
+ toPoint( theFeature->attribute(SketchPlugin_Line::END_ID()) );
+ aLine = std::shared_ptr<GeomAPI_Lin2d>(new GeomAPI_Lin2d(aStart, aEnd));
}
+ return aLine;
}
-/// \brief Find intersections of two circles with extended radii
-void possibleFilletCenterArcArc(
- std::shared_ptr<GeomAPI_XY> theCenterA, double theRadiusA,
- std::shared_ptr<GeomAPI_XY> theCenterB, double theRadiusB,
- double theRadius, std::list< std::shared_ptr<GeomAPI_XY> >& theCenters)
+static std::shared_ptr<GeomAPI_Circ2d> toCircle(const FeaturePtr& theFeature)
{
- std::shared_ptr<GeomAPI_XY> aCenterDir = theCenterB->decreased(theCenterA);
- double aCenterDist2 = aCenterDir->dot(aCenterDir);
- double aCenterDist = sqrt(aCenterDist2);
-
- double aRadA, aRadB;
- for (double aStepA = -1.0; aStepA <= 1.0; aStepA += 2.0) {
- aRadA = theRadiusA + aStepA * theRadius;
- for (double aStepB = -1.0; aStepB <= 1.0; aStepB += 2.0) {
- aRadB = theRadiusB + aStepB * theRadius;
- if (aRadA + aRadB < aCenterDist || fabs(aRadA - aRadB) > aCenterDist)
- continue; // there is no intersections
-
- double aMedDist = (aRadA * aRadA - aRadB * aRadB + aCenterDist2) / (2.0 * aCenterDist);
- double aHeight = sqrt(aRadA * aRadA - aMedDist * aMedDist);
-
- double x1 = theCenterA->x() +
- (aMedDist * aCenterDir->x() + aCenterDir->y() * aHeight) / aCenterDist;
- double y1 = theCenterA->y() +
- (aMedDist * aCenterDir->y() - aCenterDir->x() * aHeight) / aCenterDist;
-
- double x2 = theCenterA->x() +
- (aMedDist * aCenterDir->x() - aCenterDir->y() * aHeight) / aCenterDist;
- double y2 = theCenterA->y() +
- (aMedDist * aCenterDir->y() + aCenterDir->x() * aHeight) / aCenterDist;
-
- std::shared_ptr<GeomAPI_XY> aPoint1(new GeomAPI_XY(x1, y1));
- theCenters.push_back(aPoint1);
- std::shared_ptr<GeomAPI_XY> aPoint2(new GeomAPI_XY(x2, y2));
- theCenters.push_back(aPoint2);
- }
+ std::shared_ptr<GeomAPI_Circ2d> aCircle;
+ if (theFeature->getKind() == SketchPlugin_Arc::ID()) {
+ std::shared_ptr<GeomAPI_Pnt2d> aCenter =
+ toPoint( theFeature->attribute(SketchPlugin_Arc::CENTER_ID()) );
+ std::shared_ptr<GeomAPI_Pnt2d> aStart =
+ toPoint( theFeature->attribute(SketchPlugin_Arc::START_ID()) );
+ aCircle = std::shared_ptr<GeomAPI_Circ2d>(new GeomAPI_Circ2d(aCenter, aStart));
}
+ return aCircle;
}
-void calculateFilletCenter(FeaturePtr theFeatureA, FeaturePtr theFeatureB,
- double theRadius, bool theNotInversed[2],
+
+void calculateFilletCenter(FeaturePtr theFilletFeatures[2],
+ double theFilletRadius,
+ const std::shared_ptr<GeomAPI_Ax3>& theSketchPlane,
std::shared_ptr<GeomAPI_XY>& theCenter,
std::shared_ptr<GeomAPI_XY>& theTangentA,
std::shared_ptr<GeomAPI_XY>& theTangentB)
{
- static const int aNbFeatures = 2;
- FeaturePtr aFeature[aNbFeatures] = {theFeatureA, theFeatureB};
- std::shared_ptr<GeomAPI_XY> aStart[aNbFeatures], aEnd[aNbFeatures], aCenter[aNbFeatures];
- std::shared_ptr<GeomDataAPI_Point2D> aStartPoint, aEndPoint;
-
- for (int i = 0; i < aNbFeatures; i++) {
- if (aFeature[i]->getKind() == SketchPlugin_Line::ID()) {
- aStartPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
- aFeature[i]->attribute(SketchPlugin_Line::START_ID()));
- aEndPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
- aFeature[i]->attribute(SketchPlugin_Line::END_ID()));
- } else if (aFeature[i]->getKind() == SketchPlugin_Arc::ID()) {
- aStartPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
- aFeature[i]->attribute(SketchPlugin_Arc::START_ID()));
- aEndPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
- aFeature[i]->attribute(SketchPlugin_Arc::END_ID()));
- aCenter[i] = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
- aFeature[i]->attribute(SketchPlugin_Arc::CENTER_ID()))->pnt()->xy();
- } else
- return;
- aStart[i] = std::shared_ptr<GeomAPI_XY>(theNotInversed[i] ?
- new GeomAPI_XY(aStartPoint->x(), aStartPoint->y()) :
- new GeomAPI_XY(aEndPoint->x(), aEndPoint->y()));
- aEnd[i] = std::shared_ptr<GeomAPI_XY>(theNotInversed[i] ?
- new GeomAPI_XY(aEndPoint->x(), aEndPoint->y()) :
- new GeomAPI_XY(aStartPoint->x(), aStartPoint->y()));
- }
-
- if (theFeatureA->getKind() == SketchPlugin_Line::ID() &&
- theFeatureB->getKind() == SketchPlugin_Line::ID()) {
- std::shared_ptr<GeomAPI_Dir2d> aDir[2];
- std::shared_ptr<GeomAPI_Dir2d> aDirT[2];
- for (int i = 0; i < aNbFeatures; i++) {
- aDir[i] = std::shared_ptr<GeomAPI_Dir2d>(new GeomAPI_Dir2d(aEnd[i]->decreased(aStart[i])));
- aDirT[i] = std::shared_ptr<GeomAPI_Dir2d>(new GeomAPI_Dir2d(-aDir[i]->y(), aDir[i]->x()));
+ GeomShapePtr aShapeA = theFilletFeatures[0]->lastResult()->shape();
+ GeomShapePtr aShapeB = theFilletFeatures[1]->lastResult()->shape();
+
+ GeomAlgoAPI_Circ2dBuilder aCircBuilder(theSketchPlane);
+ aCircBuilder.addTangentCurve(aShapeA);
+ aCircBuilder.addTangentCurve(aShapeB);
+ aCircBuilder.setRadius(theFilletRadius);
+
+ std::shared_ptr<GeomAPI_Circ2d> aFilletCircle = aCircBuilder.circle();
+ if (!aFilletCircle)
+ return;
+
+ theCenter = aFilletCircle->center()->xy();
+ // tangent points
+ std::shared_ptr<GeomAPI_Pnt2d> aTgPoints[2];
+ for (int i = 0; i < 2; ++i) {
+ std::shared_ptr<GeomAPI_Circ2d> aCircle = toCircle(theFilletFeatures[i]);
+ if (aCircle)
+ aTgPoints[i] = aCircle->project(aFilletCircle->center());
+ else {
+ std::shared_ptr<GeomAPI_Lin2d> aLine = toLine(theFilletFeatures[i]);
+ if (aLine)
+ aTgPoints[i] = aLine->project(aFilletCircle->center());
}
-
- // get and filter possible centers
- std::list< std::shared_ptr<GeomAPI_XY> > aSuspectCenters;
- possibleFilletCenterLineLine(aStart[0], aDir[0], aStart[1], aDir[1],
- theRadius, aSuspectCenters);
- double aDot = 0.0;
- std::list< std::shared_ptr<GeomAPI_XY> >::iterator anIt = aSuspectCenters.begin();
- for (; anIt != aSuspectCenters.end(); anIt++) {
- aDot = aDirT[0]->xy()->dot(aStart[0]->decreased(*anIt));
- theTangentA = (*anIt)->added(aDirT[0]->xy()->multiplied(aDot));
- if (theTangentA->decreased(aStart[0])->dot(aDir[0]->xy()) < 0.0)
- continue; // incorrect position
- aDot = aDirT[1]->xy()->dot(aStart[1]->decreased(*anIt));
- theTangentB = (*anIt)->added(aDirT[1]->xy()->multiplied(aDot));
- if (theTangentB->decreased(aStart[1])->dot(aDir[1]->xy()) < 0.0)
- continue; // incorrect position
- // the center is found, stop searching
- theCenter = *anIt;
- return;
- }
- } else if ((theFeatureA->getKind() == SketchPlugin_Arc::ID() &&
- theFeatureB->getKind() == SketchPlugin_Line::ID()) ||
- (theFeatureA->getKind() == SketchPlugin_Line::ID() &&
- theFeatureB->getKind() == SketchPlugin_Arc::ID())) {
- int aLineInd = theFeatureA->getKind() == SketchPlugin_Line::ID() ? 0 : 1;
- double anArcRadius = aStart[1-aLineInd]->distance(aCenter[1-aLineInd]);
- std::shared_ptr<GeomAPI_Dir2d> aDirLine = std::shared_ptr<GeomAPI_Dir2d>(
- new GeomAPI_Dir2d(aEnd[aLineInd]->decreased(aStart[aLineInd])));
- std::shared_ptr<GeomAPI_Dir2d> aDirT = std::shared_ptr<GeomAPI_Dir2d>(
- new GeomAPI_Dir2d(-aDirLine->y(), aDirLine->x()));
-
- std::shared_ptr<GeomAPI_Dir2d> aStartArcDir = std::shared_ptr<GeomAPI_Dir2d>(
- new GeomAPI_Dir2d(aStart[1-aLineInd]->decreased(aCenter[1-aLineInd])));
- std::shared_ptr<GeomAPI_Dir2d> aEndArcDir = std::shared_ptr<GeomAPI_Dir2d>(
- new GeomAPI_Dir2d(aEnd[1-aLineInd]->decreased(aCenter[1-aLineInd])));
- double anArcAngle = aEndArcDir->angle(aStartArcDir);
-
- // get possible centers and filter them
- std::list< std::shared_ptr<GeomAPI_XY> > aSuspectCenters;
- possibleFilletCenterLineArc(aStart[aLineInd], aDirLine, aCenter[1-aLineInd],
- anArcRadius, theRadius, aSuspectCenters);
- double aDot = 0.0;
- // the line is forward into the arc
- double innerArc = aCenter[1-aLineInd]->decreased(aStart[aLineInd])->dot(aDirLine->xy());
- std::shared_ptr<GeomAPI_XY> aLineTgPoint, anArcTgPoint;
- // The possible centers are ranged by their positions.
- // If the point is not satisfy one of criteria, the weight is decreased with penalty.
- int aBestWeight = 0;
- std::list< std::shared_ptr<GeomAPI_XY> >::iterator anIt = aSuspectCenters.begin();
- for (; anIt != aSuspectCenters.end(); anIt++) {
- int aWeight = 2;
- aDot = aDirT->xy()->dot(aStart[aLineInd]->decreased(*anIt));
- aLineTgPoint = (*anIt)->added(aDirT->xy()->multiplied(aDot));
- // Check the point is placed on the correct arc (penalty if false)
- if (aCenter[1-aLineInd]->distance(*anIt) * innerArc > anArcRadius * innerArc)
- aWeight -= 1;
- std::shared_ptr<GeomAPI_Dir2d> aCurDir = std::shared_ptr<GeomAPI_Dir2d>(
- new GeomAPI_Dir2d((*anIt)->decreased(aCenter[1-aLineInd])));
- double aCurAngle = aCurDir->angle(aStartArcDir);
- if (anArcAngle < 0.0) aCurAngle *= -1.0;
- if (aCurAngle < 0.0 || aCurAngle > fabs(anArcAngle))
- continue;
- if (aWeight > aBestWeight)
- aBestWeight = aWeight;
- else if (aWeight < aBestWeight ||
- aStart[aLineInd]->distance(*anIt) >
- aStart[aLineInd]->distance(theCenter)) // <-- take closer point
- continue;
- // the center is found, stop searching
- theCenter = *anIt;
- anArcTgPoint = aCenter[1-aLineInd]->added(aCurDir->xy()->multiplied(anArcRadius));
- if (theFeatureA->getKind() == SketchPlugin_Line::ID()) {
- theTangentA = aLineTgPoint;
- theTangentB = anArcTgPoint;
- } else {
- theTangentA = anArcTgPoint;
- theTangentB = aLineTgPoint;
- }
- //return;
- }
- } else if (theFeatureA->getKind() == SketchPlugin_Arc::ID() &&
- theFeatureB->getKind() == SketchPlugin_Arc::ID()) {
- double anArcRadius[aNbFeatures];
- double anArcAngle[aNbFeatures];
- std::shared_ptr<GeomAPI_Dir2d> aStartArcDir[aNbFeatures];
- for (int i = 0; i < aNbFeatures; i++) {
- anArcRadius[i] = aStart[i]->distance(aCenter[i]);
- aStartArcDir[i] = std::shared_ptr<GeomAPI_Dir2d>(
- new GeomAPI_Dir2d(aStart[i]->decreased(aCenter[i])));
- std::shared_ptr<GeomAPI_Dir2d> aEndArcDir = std::shared_ptr<GeomAPI_Dir2d>(
- new GeomAPI_Dir2d(aEnd[i]->decreased(aCenter[i])));
- anArcAngle[i] = aEndArcDir->angle(aStartArcDir[i]);
- }
-
- // get and filter possible centers
- std::list< std::shared_ptr<GeomAPI_XY> > aSuspectCenters;
- possibleFilletCenterArcArc(aCenter[0], anArcRadius[0], aCenter[1],
- anArcRadius[1], theRadius, aSuspectCenters);
- double aDot = 0.0;
- std::shared_ptr<GeomAPI_XY> aLineTgPoint, anArcTgPoint;
- std::list< std::shared_ptr<GeomAPI_XY> >::iterator anIt = aSuspectCenters.begin();
- for (; anIt != aSuspectCenters.end(); anIt++) {
- std::shared_ptr<GeomAPI_Dir2d> aCurDir = std::shared_ptr<GeomAPI_Dir2d>(
- new GeomAPI_Dir2d((*anIt)->decreased(aCenter[0])));
- double aCurAngle = aCurDir->angle(aStartArcDir[0]);
- if (anArcAngle[0] < 0.0) aCurAngle *= -1.0;
- if (aCurAngle < 0.0 || aCurAngle > fabs(anArcAngle[0]))
- continue; // incorrect position
- theTangentA = aCenter[0]->added(aCurDir->xy()->multiplied(anArcRadius[0]));
-
- aCurDir = std::shared_ptr<GeomAPI_Dir2d>(new GeomAPI_Dir2d((*anIt)->decreased(aCenter[1])));
- aCurAngle = aCurDir->angle(aStartArcDir[1]);
- if (anArcAngle[1] < 0.0) aCurAngle *= -1.0;
- if (aCurAngle < 0.0 || aCurAngle > fabs(anArcAngle[1]))
- continue; // incorrect position
- theTangentB = aCenter[1]->added(aCurDir->xy()->multiplied(anArcRadius[1]));
-
- // the center is found, stop searching
- theCenter = *anIt;
- return;
- }
- }
-}
-
-void getPointOnEdge(const FeaturePtr theFeature,
- const std::shared_ptr<GeomAPI_Pnt2d> theFilletPoint,
- std::shared_ptr<GeomAPI_Pnt2d>& thePoint) {
- if(theFeature->getKind() == SketchPlugin_Line::ID()) {
- std::shared_ptr<GeomAPI_Pnt2d> aPntStart = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
- theFeature->attribute(SketchPlugin_Line::START_ID()))->pnt();
- std::shared_ptr<GeomAPI_Pnt2d> aPntEnd = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
- theFeature->attribute(SketchPlugin_Line::END_ID()))->pnt();
- if(aPntStart->distance(theFilletPoint) > 1.e-7) {
- aPntStart = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
- theFeature->attribute(SketchPlugin_Line::END_ID()))->pnt();
- aPntEnd = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
- theFeature->attribute(SketchPlugin_Line::START_ID()))->pnt();
- }
- thePoint.reset(
- new GeomAPI_Pnt2d(aPntStart->xy()->added(
- aPntEnd->xy()->decreased( aPntStart->xy() )->multiplied(1.0 / 3.0) ) ) );
- } else {
- std::shared_ptr<GeomAPI_Pnt2d> aPntTemp;
- std::shared_ptr<GeomAPI_Pnt2d> aPntStart = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
- theFeature->attribute(SketchPlugin_Arc::START_ID()))->pnt();
- std::shared_ptr<GeomAPI_Pnt2d> aPntEnd = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
- theFeature->attribute(SketchPlugin_Arc::END_ID()))->pnt();
- if(theFeature->attribute(SketchPlugin_Arc::REVERSED_ID())) {
- aPntTemp = aPntStart;
- aPntStart = aPntEnd;
- aPntEnd = aPntTemp;
- }
- std::shared_ptr<GeomAPI_Pnt2d> aCenterPnt = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
- theFeature->attribute(SketchPlugin_Arc::CENTER_ID()))->pnt();
- std::shared_ptr<GeomAPI_Circ2d> aCirc(new GeomAPI_Circ2d(aCenterPnt, aPntStart));
- double aStartParameter(0), anEndParameter(0);
- aCirc->parameter(aPntStart, paramTolerance, aStartParameter);
- aCirc->parameter(aPntEnd, paramTolerance, anEndParameter);
- if(aPntStart->distance(theFilletPoint) > tolerance) {
- double aTmpParameter = aStartParameter;
- aStartParameter = anEndParameter;
- anEndParameter = aTmpParameter;
- }
- double aPntParameter = aStartParameter + (anEndParameter - aStartParameter) / 3.0;
- aCirc->D0(aPntParameter, thePoint);
}
+ theTangentA = aTgPoints[0]->xy();
+ theTangentB = aTgPoints[1]->xy();
}
-double getProjectionDistance(const FeaturePtr theFeature,
- const std::shared_ptr<GeomAPI_Pnt2d> thePoint)
+double calculateFilletRadius(FeaturePtr theFilletFeatures[2])
{
- std::shared_ptr<GeomAPI_Pnt2d> aProjectPnt;
- if(theFeature->getKind() == SketchPlugin_Line::ID()) {
- std::shared_ptr<GeomAPI_Pnt2d> aPntStart = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
- theFeature->attribute(SketchPlugin_Line::START_ID()))->pnt();
- std::shared_ptr<GeomAPI_Pnt2d> aPntEnd = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
- theFeature->attribute(SketchPlugin_Line::END_ID()))->pnt();
- std::shared_ptr<GeomAPI_Lin2d> aLin(new GeomAPI_Lin2d(aPntStart, aPntEnd));
- aProjectPnt = aLin->project(thePoint);
- } else {
- std::shared_ptr<GeomAPI_Pnt2d> aPntStart = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
- theFeature->attribute(SketchPlugin_Arc::START_ID()))->pnt();
- std::shared_ptr<GeomAPI_Pnt2d> aPntEnd = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
- theFeature->attribute(SketchPlugin_Arc::END_ID()))->pnt();
- std::shared_ptr<GeomAPI_Pnt2d> aCenterPnt = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
- theFeature->attribute(SketchPlugin_Arc::CENTER_ID()))->pnt();
- std::shared_ptr<GeomAPI_Circ2d> aCirc(new GeomAPI_Circ2d(aCenterPnt, aPntStart));
- aProjectPnt = aCirc->project(thePoint);
- }
- if(aProjectPnt.get()) {
- return aProjectPnt->distance(thePoint);
+ double aLengths[2] = { 0, 0 };
+ for (int i = 0; i < 2; ++i) {
+ GeomShapePtr aShape = theFilletFeatures[i]->lastResult()->shape();
+ std::shared_ptr<GeomAPI_Edge> anEdge = std::dynamic_pointer_cast<GeomAPI_Edge>(aShape);
+ if (anEdge)
+ aLengths[i] = anEdge->length();
}
- return -1;
+ return std::min(aLengths[0], aLengths[1]) / 6.0;
}
std::set<FeaturePtr> getCoincides(const FeaturePtr& theConstraintCoincidence)
/// Reimplemented from ModelAPI_Feature::isMacro().
/// \returns true
- SKETCHPLUGIN_EXPORT virtual bool isMacro() const {return true;};
+ SKETCHPLUGIN_EXPORT virtual bool isMacro() const {return true;}
- SKETCHPLUGIN_EXPORT virtual bool isPreviewNeeded() const {return false;};
+ SKETCHPLUGIN_EXPORT virtual bool isPreviewNeeded() const {return false;}
/// Reimplemented from SketchPlugin_Feature::move().
/// Do nothing.
- SKETCHPLUGIN_EXPORT virtual void move(const double theDeltaX, const double theDeltaY) {};
+ SKETCHPLUGIN_EXPORT virtual void move(const double, const double) {}
/// \brief Use plugin manager for features creation
SketchPlugin_Fillet();
#include "SketchPlugin_Line.h"
#include "SketchPlugin_Sketch.h"
+#include "SketchPlugin_ConstraintCoincidence.h"
+
#include <ModelAPI_Data.h>
+#include <ModelAPI_EventReentrantMessage.h>
#include <ModelAPI_ResultConstruction.h>
#include <ModelAPI_AttributeSelection.h>
#include <ModelAPI_AttributeBoolean.h>
aConstr->setShape(anEdge);
aConstr->setIsInHistory(false);
setResult(aConstr);
+
+ static Events_ID anId = ModelAPI_EventReentrantMessage::eventId();
+ std::shared_ptr<ModelAPI_EventReentrantMessage> aMessage = std::shared_ptr
+ <ModelAPI_EventReentrantMessage>(new ModelAPI_EventReentrantMessage(anId, 0));
+ aMessage->setCreatedFeature(ModelAPI_Feature::feature(
+ data()->attribute(START_ID())->owner()));
+ Events_Loop::loop()->send(aMessage);
}
}
}
aPoint2->move(theDeltaX, theDeltaY);
}
+std::string SketchPlugin_Line::processEvent(const std::shared_ptr<Events_Message>& theMessage)
+{
+ std::string aFilledAttributeName;
+
+ std::shared_ptr<ModelAPI_EventReentrantMessage> aReentrantMessage =
+ std::dynamic_pointer_cast<ModelAPI_EventReentrantMessage>(theMessage);
+ if (aReentrantMessage.get()) {
+ FeaturePtr aCreatedFeature = aReentrantMessage->createdFeature();
+
+ // Initialize new line with first point equal to end of previous
+ std::shared_ptr<ModelAPI_Data> aSFData = aCreatedFeature->data();
+ std::shared_ptr<GeomDataAPI_Point2D> aSPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ aSFData->attribute(SketchPlugin_Line::END_ID()));
+ std::shared_ptr<ModelAPI_Data> aNFData = data();
+ std::shared_ptr<GeomDataAPI_Point2D> aNPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ aNFData->attribute(SketchPlugin_Line::START_ID()));
+ aNPoint->setValue(aSPoint->x(), aSPoint->y());
+ SketchPlugin_ConstraintCoincidence::createCoincidenceFeature(sketch(), aSPoint, aNPoint);
+ }
+ return aFilledAttributeName;
+}
+
double SketchPlugin_Line::distanceToPoint(const std::shared_ptr<GeomAPI_Pnt2d>& thePoint)
{
double aDelta = 0;
#ifndef SketchPlugin_Line_H_
#define SketchPlugin_Line_H_
+#include <ModelAPI_IReentrant.h>
+
#include "SketchPlugin.h"
#include <SketchPlugin_SketchEntity.h>
#include <SketchPlugin_Sketch.h>
* \ingroup Plugins
* \brief Feature for creation of the new part in PartSet.
*/
-class SketchPlugin_Line : public SketchPlugin_SketchEntity
+class SketchPlugin_Line : public SketchPlugin_SketchEntity,
+ public ModelAPI_IReentrant
{
public:
/// Arc feature kind
/// \param theDeltaY the delta for Y coordinate is moved
SKETCHPLUGIN_EXPORT virtual void move(const double theDeltaX, const double theDeltaY);
+ /// Apply information of the message to current object. It fills start attribute of
+ /// the currrent feature by last attribute of the message feature, build coincidence
+ /// if message has selected object
+ virtual std::string processEvent(const std::shared_ptr<Events_Message>& theMessage);
+
/// Return the distance between the feature and the point
/// \param thePoint the point
double distanceToPoint(const std::shared_ptr<GeomAPI_Pnt2d>& thePoint);
#include "SketchPlugin_ConstraintTangent.h"
#include "SketchPlugin_Sketch.h"
#include "SketchPlugin_Tools.h"
+#include "SketchPlugin_MacroArcReentrantMessage.h"
#include <ModelAPI_AttributeDouble.h>
#include <ModelAPI_AttributeRefAttr.h>
#include <ModelAPI_AttributeString.h>
+#include <ModelAPI_Events.h>
#include <ModelAPI_Session.h>
#include <ModelAPI_Validator.h>
#include <GeomAPI_Pnt2d.h>
#include <GeomAPI_Vertex.h>
#include <GeomAPI_XY.h>
+#include <GeomAPI_ShapeIterator.h>
#include <GeomDataAPI_Point2D.h>
#include <GeomDataAPI_Dir.h>
-#include <GeomAlgoAPI_PointBuilder.h>
+
+#include <GeomAlgoAPI_Circ2dBuilder.h>
#include <GeomAlgoAPI_EdgeBuilder.h>
#include <GeomAlgoAPI_CompoundBuilder.h>
+#include <GeomAlgoAPI_PointBuilder.h>
// for sqrt on Linux
#include <math.h>
thePoint->setValue(aProjection);
}
+static void intersectShapeAndCircle(const GeomShapePtr& theShape,
+ const GeomAPI_Circ2d& theCircle,
+ const SketchPlugin_Sketch* theSketch,
+ AttributePoint2DPtr& theIntersection)
+{
+ if (!theShape->isEdge())
+ return projectPointOnCircle(theIntersection, theCircle);
+
+ // convert shape to unbounded
+ std::shared_ptr<GeomAPI_Edge> anEdge(new GeomAPI_Edge(theShape));
+ if (anEdge->isLine()) {
+ static const double HALF_SIZE = 1.e6;
+ std::shared_ptr<GeomAPI_XYZ> aLoc = anEdge->line()->location()->xyz();
+ std::shared_ptr<GeomAPI_XYZ> aDir = anEdge->line()->direction()->xyz();
+
+ std::shared_ptr<GeomAPI_Pnt> aStart(
+ new GeomAPI_Pnt(aLoc->added(aDir->multiplied(-HALF_SIZE))));
+ std::shared_ptr<GeomAPI_Pnt> aEnd(
+ new GeomAPI_Pnt(aLoc->added(aDir->multiplied(HALF_SIZE))));
+ anEdge = GeomAlgoAPI_EdgeBuilder::line(aStart, aEnd);
+ } else if (anEdge->isArc()) {
+ std::shared_ptr<GeomAPI_Circ> aCircle = anEdge->circle();
+ anEdge = GeomAlgoAPI_EdgeBuilder::lineCircle(
+ aCircle->center(), aCircle->normal(), aCircle->radius());
+ }
+
+ // convert 2D circle to 3D object
+ std::shared_ptr<GeomAPI_Pnt2d> aCenter2d = theCircle.center();
+ std::shared_ptr<GeomAPI_Pnt> aCenter(theSketch->to3D(aCenter2d->x(), aCenter2d->y()));
+ std::shared_ptr<GeomDataAPI_Dir> aNDir = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
+ const_cast<SketchPlugin_Sketch*>(theSketch)->attribute(SketchPlugin_Sketch::NORM_ID()));
+ std::shared_ptr<GeomAPI_Dir> aNormal(new GeomAPI_Dir(aNDir->x(), aNDir->y(), aNDir->z()));
+
+ GeomShapePtr aCircleShape =
+ GeomAlgoAPI_EdgeBuilder::lineCircle(aCenter, aNormal, theCircle.radius());
+
+ GeomShapePtr anInter = anEdge->intersect(aCircleShape);
+ std::shared_ptr<GeomAPI_Pnt2d> anInterPnt;
+ if (!anInter)
+ return projectPointOnCircle(theIntersection, theCircle);
+ if (anInter->isVertex()) {
+ std::shared_ptr<GeomAPI_Vertex> aVertex(new GeomAPI_Vertex(anInter));
+ anInterPnt = theSketch->to2D(aVertex->point());
+ } else if (anInter->isCompound()) {
+ double aMinDist = 1.e300;
+
+ GeomAPI_ShapeIterator anIt(anInter);
+ for (; anIt.more(); anIt.next()) {
+ GeomShapePtr aCurrent = anIt.current();
+ if (!aCurrent->isVertex())
+ continue;
+ std::shared_ptr<GeomAPI_Vertex> aVertex(new GeomAPI_Vertex(aCurrent));
+ std::shared_ptr<GeomAPI_Pnt2d> aPnt = theSketch->to2D(aVertex->point());
+ double aDist = aPnt->distance(theIntersection->pnt());
+ if (aDist < aMinDist) {
+ aMinDist = aDist;
+ anInterPnt = aPnt;
+ }
+ }
+ }
+ theIntersection->setValue(anInterPnt);
+}
+
SketchPlugin_MacroArc::SketchPlugin_MacroArc()
: SketchPlugin_SketchEntity(),
data()->addAttribute(END_POINT_REF_ID(), ModelAPI_AttributeRefAttr::typeId());
data()->addAttribute(PASSED_POINT_REF_ID(), ModelAPI_AttributeRefAttr::typeId());
+ data()->addAttribute(EDIT_ARC_TYPE_ID(), ModelAPI_AttributeString::typeId());
+
boolean(REVERSED_ID())->setValue(false);
+ string(EDIT_ARC_TYPE_ID())->setValue("");
ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), CENTER_POINT_REF_ID());
ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), START_POINT_REF_ID());
ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), END_POINT_REF_ID());
ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), PASSED_POINT_REF_ID());
+ ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), EDIT_ARC_TYPE_ID());
}
void SketchPlugin_MacroArc::attributeChanged(const std::string& theID)
}
bool aWasBlocked = data()->blockSendAttributeUpdated(true);
+ if(myCenter.get()) {
+ // center attribute is used in processEvent() to set reference to reentrant arc
+ std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(CENTER_POINT_ID()))
+ ->setValue(myCenter);
+ }
real(RADIUS_ID())->setValue(aRadius);
real(ANGLE_ID())->setValue(anAngle);
data()->blockSendAttributeUpdated(aWasBlocked, false);
}
-GeomShapePtr SketchPlugin_MacroArc::getArcShape()
+GeomShapePtr SketchPlugin_MacroArc::getArcShape(bool isBound)
{
if(!myStart.get() || !myEnd.get() || !myCenter.get()) {
return GeomShapePtr();
std::dynamic_pointer_cast<GeomDataAPI_Dir>(aSketch->attribute(SketchPlugin_Sketch::NORM_ID()));
std::shared_ptr<GeomAPI_Dir> aNormal(new GeomAPI_Dir(aNDir->x(), aNDir->y(), aNDir->z()));
- GeomShapePtr anArcShape = boolean(REVERSED_ID())->value() ?
- GeomAlgoAPI_EdgeBuilder::lineCircleArc(aCenter, anEnd, aStart, aNormal)
- : GeomAlgoAPI_EdgeBuilder::lineCircleArc(aCenter, aStart, anEnd, aNormal);
+ GeomShapePtr anArcShape;
+ if (isBound) {
+ anArcShape = boolean(REVERSED_ID())->value() ?
+ GeomAlgoAPI_EdgeBuilder::lineCircleArc(aCenter, anEnd, aStart, aNormal)
+ : GeomAlgoAPI_EdgeBuilder::lineCircleArc(aCenter, aStart, anEnd, aNormal);
+ } else {
+ double aRadius = aCenter->distance(aStart);
+ anArcShape = GeomAlgoAPI_EdgeBuilder::lineCircle(aCenter, aNormal, aRadius);
+ }
return anArcShape;
}
ObjectPtr(),
false);
}
+
+ // message to init reentrant operation
+ static Events_ID anId = SketchPlugin_MacroArcReentrantMessage::eventId();
+ std::shared_ptr<SketchPlugin_MacroArcReentrantMessage> aMessage = std::shared_ptr
+ <SketchPlugin_MacroArcReentrantMessage>(new SketchPlugin_MacroArcReentrantMessage(anId, 0));
+
+ std::string anEditArcType = string(EDIT_ARC_TYPE_ID())->value();
+ aMessage->setTypeOfCreation(!anEditArcType.empty() ? anEditArcType : anArcType);
+ aMessage->setCreatedFeature(anArcFeature);
+ Events_Loop::loop()->send(aMessage);
+}
+
+std::string SketchPlugin_MacroArc::processEvent(const std::shared_ptr<Events_Message>& theMessage)
+{
+ std::string aFilledAttributeName;
+ std::shared_ptr<SketchPlugin_MacroArcReentrantMessage> aReentrantMessage =
+ std::dynamic_pointer_cast<SketchPlugin_MacroArcReentrantMessage>(theMessage);
+ if (aReentrantMessage.get()) {
+ FeaturePtr aCreatedFeature = aReentrantMessage->createdFeature();
+ std::string anArcType = aReentrantMessage->typeOfCreation();
+
+ string(ARC_TYPE())->setValue(anArcType);
+
+ aFilledAttributeName = ARC_TYPE();
+ if(anArcType == ARC_TYPE_BY_TANGENT_EDGE()) {
+ aFilledAttributeName = TANGENT_POINT_ID();
+ AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+ attribute(aFilledAttributeName));
+ FeaturePtr aCreatedFeature = aReentrantMessage->createdFeature();
+ aRefAttr->setAttr(aCreatedFeature->attribute(SketchPlugin_Arc::END_ID()));
+ }
+ else {
+ ObjectPtr anObject = aReentrantMessage->selectedObject();
+ AttributePtr anAttribute = aReentrantMessage->selectedAttribute();
+ std::shared_ptr<GeomAPI_Pnt2d> aClickedPoint = aReentrantMessage->clickedPoint();
+
+ if (aClickedPoint.get() && (anObject.get() || anAttribute.get())) {
+ if (anArcType == ARC_TYPE_BY_CENTER_AND_POINTS() ||
+ anArcType == ARC_TYPE_BY_THREE_POINTS()) {
+ std::string aReferenceAttributeName;
+ if (anArcType == ARC_TYPE_BY_CENTER_AND_POINTS()) {
+ aFilledAttributeName = CENTER_POINT_ID();
+ aReferenceAttributeName = CENTER_POINT_REF_ID();
+ }
+ else {
+ aFilledAttributeName = START_POINT_2_ID();
+ aReferenceAttributeName = START_POINT_REF_ID();
+ }
+ // fill 2d point attribute
+ AttributePoint2DPtr aPointAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ attribute(aFilledAttributeName));
+ aPointAttr->setValue(aClickedPoint);
+ // fill reference attribute
+ AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+ attribute(aReferenceAttributeName));
+ if (aRefAttr.get()) {
+ if (anAttribute.get()) {
+ if (!anAttribute->owner().get() || !anAttribute->owner()->data()->isValid()) {
+ FeaturePtr aCreatedFeature = aReentrantMessage->createdFeature();
+ if (aCreatedFeature.get()) {
+ std::string anID = anAttribute->id();
+ std::string anArcID;
+ if (anID == END_POINT_1_ID() || anID == END_POINT_2_ID() ||
+ anID == END_POINT_3_ID())
+ anArcID = SketchPlugin_Arc::END_ID();
+ else if (anID == START_POINT_1_ID() || anID ==START_POINT_2_ID())
+ anArcID = SketchPlugin_Arc::START_ID();
+ else if (anID == CENTER_POINT_ID())
+ anArcID = SketchPlugin_Arc::CENTER_ID();
+ anAttribute = aCreatedFeature->attribute(anArcID);
+ }
+ }
+ aRefAttr->setAttr(anAttribute);
+ }
+ else if (anObject.get()) {
+ // if presentation of previous reentrant macro arc is used, the object is invalid,
+ // we should use result of previous feature of the message(Arc)
+ if (!anObject->data()->isValid()) {
+ FeaturePtr aCreatedFeature = aReentrantMessage->createdFeature();
+ if (aCreatedFeature.get())
+ anObject = aCreatedFeature->lastResult();
+ }
+ aRefAttr->setObject(anObject);
+ }
+ }
+ }
+ }
+ }
+ Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
+ }
+ return aFilledAttributeName;
}
FeaturePtr SketchPlugin_MacroArc::createArcFeature()
GeomAPI_Circ2d aCircleForArc(myCenter, myStart);
- // End point should be a projection on circle.
bool aWasBlocked = data()->blockSendAttributeUpdated(true);
- projectPointOnCircle(anEndPointAttr, aCircleForArc);
+ // check the end point is referred to another feature
+ GeomShapePtr aRefShape;
+ AttributeRefAttrPtr aEndPointRefAttr = refattr(END_POINT_REF_ID());
+ if (aEndPointRefAttr && aEndPointRefAttr->isInitialized()) {
+ if (aEndPointRefAttr->isObject()) {
+ FeaturePtr aFeature = ModelAPI_Feature::feature(aEndPointRefAttr->object());
+ if (aFeature)
+ aRefShape = aFeature->lastResult()->shape();
+ }
+ }
+ if (aRefShape) {
+ // Calculate end point as an intersection between circle and another shape
+ intersectShapeAndCircle(aRefShape, aCircleForArc, sketch(), anEndPointAttr);
+ } else {
+ // End point should be a projection on circle.
+ projectPointOnCircle(anEndPointAttr, aCircleForArc);
+ }
data()->blockSendAttributeUpdated(aWasBlocked, false);
myEnd = anEndPointAttr->pnt();
SketchPlugin_Tools::convertRefAttrToPointOrTangentCurve(
refattr(PASSED_POINT_REF_ID()), aPassedPointAttr, aTangentCurve, aPassedPnt);
- std::shared_ptr<GeomAPI_Interface> aPassed;
- if (aTangentCurve)
- aPassed = aTangentCurve;
- else
- aPassed = aPassedPnt;
-
- std::shared_ptr<GeomAPI_Ax3> anAxis = SketchPlugin_Sketch::plane(sketch());
- GeomAPI_Circ2d aCircle(myStart, myEnd, aPassed, anAxis);
- myCenter = aCircle.center();
+ GeomAlgoAPI_Circ2dBuilder aCircBuilder(SketchPlugin_Sketch::plane(sketch()));
+ aCircBuilder.addPassingPoint(myStart);
+ aCircBuilder.addPassingPoint(myEnd);
+ if (aTangentCurve) {
+ aCircBuilder.addTangentCurve(aTangentCurve);
+ aCircBuilder.setClosestPoint(aPassedPointAttr->pnt());
+ } else
+ aCircBuilder.addPassingPoint(aPassedPnt);
+
+ std::shared_ptr<GeomAPI_Circ2d> aCircle = aCircBuilder.circle();
+ if (!aCircle)
+ return;
+ myCenter = aCircle->center();
- recalculateReversedFlagByPassed(aCircle);
+ aCircle = std::shared_ptr<GeomAPI_Circ2d>(new GeomAPI_Circ2d(myCenter, myStart));
+ recalculateReversedFlagByPassed(*aCircle);
} else
myCenter.reset(new GeomAPI_Pnt2d(myStart->xy()->added(myEnd->xy())->multiplied(0.5)));
}
FeaturePtr aTangentFeature = ModelAPI_Feature::feature(aTangentPointAttr->owner());
std::shared_ptr<GeomAPI_Shape> aTangentShape = aTangentFeature->lastResult()->shape();
- std::shared_ptr<GeomAPI_Ax3> anAxis = SketchPlugin_Sketch::plane(sketch());
- GeomAPI_Circ2d aCircle(myStart, myEnd, aTangentShape, anAxis);
- myCenter = aCircle.center();
+ GeomAlgoAPI_Circ2dBuilder aCircBuilder(SketchPlugin_Sketch::plane(sketch()));
+ aCircBuilder.addPassingPoint(myStart);
+ aCircBuilder.addPassingPoint(myEnd);
+ aCircBuilder.addTangentCurve(aTangentShape);
+
+ std::shared_ptr<GeomAPI_Circ2d> aCircle = aCircBuilder.circle();
+ myCenter = aCircle->center();
// rebuild circle to set start point equal to zero parameter
- aCircle = GeomAPI_Circ2d(myCenter, myStart);
- recalculateReversedFlagByEnd(aCircle);
+ aCircle = std::shared_ptr<GeomAPI_Circ2d>(new GeomAPI_Circ2d(myCenter, myStart));
+ recalculateReversedFlagByEnd(*aCircle);
}
#ifndef SketchPlugin_MacroArc_H_
#define SketchPlugin_MacroArc_H_
-#include "SketchPlugin.h"
+#include <ModelAPI_IReentrant.h>
+#include "SketchPlugin.h"
#include "SketchPlugin_SketchEntity.h"
#include <GeomAPI_IPresentable.h>
* it is calculated if all attributes are initialized.
*/
class SketchPlugin_MacroArc: public SketchPlugin_SketchEntity,
- public GeomAPI_IPresentable
+ public GeomAPI_IPresentable,
+ public ModelAPI_IReentrant
{
public:
/// Arc feature kind
return ID;
}
+ /// Arc angle.
+ static const std::string& EDIT_ARC_TYPE_ID()
+ {
+ static const std::string ID("edit_arc_type");
+ return ID;
+ }
+
/// Returns the kind of a feature
SKETCHPLUGIN_EXPORT virtual const std::string& getKind()
{
SKETCHPLUGIN_EXPORT virtual bool isPreviewNeeded() const {return false;};
+ /// Apply information of the message to current object. It fills reference object,
+ /// tangent type and tangent point refence in case of tangent arc
+ virtual std::string processEvent(const std::shared_ptr<Events_Message>& theMessage);
+
/// Use plugin manager for features creation.
SketchPlugin_MacroArc();
/// Returns shape of arc.
- GeomShapePtr getArcShape();
+ /// \param isBound if true prepare arc, otherwice create circle containing this arc
+ GeomShapePtr getArcShape(bool isBound = true);
private:
/// Set fields for center, start and end points
--- /dev/null
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
+
+// File: SketchPlugin_MacroArcReentrantMessage.h
+// Created: 01 Apr 2017
+// Author: Natalia ERMOLAEVA
+
+#ifndef SketchPlugin_MacroArcReentrantMessage_H_
+#define SketchPlugin_MacroArcReentrantMessage_H_
+
+#include <ModelAPI_EventReentrantMessage.h>
+#include <Events_Loop.h>
+
+#include <SketchPlugin.h>
+
+#include <memory>
+
+/// Message that style of visualization of parameter is changed.
+/// It will be shown as expression or value
+class SketchPlugin_MacroArcReentrantMessage : public ModelAPI_EventReentrantMessage
+{
+public:
+ /// Creates an empty message
+ SKETCHPLUGIN_EXPORT SketchPlugin_MacroArcReentrantMessage(const Events_ID theID,
+ const void* theSender = 0)
+ : ModelAPI_EventReentrantMessage(theID, theSender) {}
+ /// The virtual destructor
+ SKETCHPLUGIN_EXPORT virtual ~SketchPlugin_MacroArcReentrantMessage() {}
+ /// Static. Returns EventID of the message.
+
+ inline static Events_ID eventId()
+ {
+ static const char * MY_EVENT_MACRO_ARC_MESSAGE_ID("MacroArcReentrantMessage");
+ return Events_Loop::eventByName(MY_EVENT_MACRO_ARC_MESSAGE_ID);
+ }
+
+ /// Stores type of creation
+ /// \param the type
+ SKETCHPLUGIN_EXPORT void setTypeOfCreation(const std::string& theType)
+ { myTypeOfCreation = theType; }
+
+ /// Returns type of creation
+ /// \return the type
+ SKETCHPLUGIN_EXPORT std::string typeOfCreation() const { return myTypeOfCreation; }
+
+private:
+ std::string myTypeOfCreation; ///< to know what parameters of new feature should be filled
+};
+
+
+#endif
#include "SketchPlugin_Circle.h"
#include "SketchPlugin_Point.h"
#include "SketchPlugin_Tools.h"
+#include "SketchPlugin_MacroArcReentrantMessage.h"
#include <ModelAPI_AttributeDouble.h>
#include <ModelAPI_AttributeRefAttr.h>
#include <ModelAPI_AttributeString.h>
#include <ModelAPI_Session.h>
#include <ModelAPI_Validator.h>
+#include <ModelAPI_Events.h>
#include <GeomDataAPI_Dir.h>
#include <GeomDataAPI_Point2D.h>
#include <GeomAPI_Pnt2d.h>
#include <GeomAPI_Vertex.h>
+#include <GeomAlgoAPI_Circ2dBuilder.h>
#include <GeomAlgoAPI_CompoundBuilder.h>
#include <GeomAlgoAPI_EdgeBuilder.h>
#include <GeomAlgoAPI_PointBuilder.h>
SketchPlugin_MacroCircle::SketchPlugin_MacroCircle()
-: SketchPlugin_SketchEntity()
+: SketchPlugin_SketchEntity(),
+ myRadius(0.0)
{
}
void SketchPlugin_MacroCircle::initAttributes()
{
data()->addAttribute(CIRCLE_TYPE(), ModelAPI_AttributeString::typeId());
+ data()->addAttribute(EDIT_CIRCLE_TYPE(), ModelAPI_AttributeString::typeId());
data()->addAttribute(CENTER_POINT_ID(), GeomDataAPI_Point2D::typeId());
data()->addAttribute(CENTER_POINT_REF_ID(), ModelAPI_AttributeRefAttr::typeId());
data()->addAttribute(CIRCLE_RADIUS_ID(), ModelAPI_AttributeDouble::typeId());
data()->addAttribute(AUXILIARY_ID(), ModelAPI_AttributeBoolean::typeId());
+ string(EDIT_CIRCLE_TYPE())->setValue("");
+
ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), CENTER_POINT_REF_ID());
ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), PASSED_POINT_REF_ID());
ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), FIRST_POINT_REF_ID());
ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), SECOND_POINT_REF_ID());
ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), THIRD_POINT_REF_ID());
+ ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), EDIT_CIRCLE_TYPE());
}
void SketchPlugin_MacroCircle::execute()
{
+ FeaturePtr aCircle = createCircleFeature();
+
std::string aType = string(CIRCLE_TYPE())->value();
if (aType == CIRCLE_TYPE_BY_CENTER_AND_PASSED_POINTS())
- createCircleByCenterAndPassed();
+ constraintsForCircleByCenterAndPassed(aCircle);
else if (aType == CIRCLE_TYPE_BY_THREE_POINTS())
- createCircleByThreePoints();
+ constraintsForCircleByThreePoints(aCircle);
+
+ // message to init reentrant operation
+ static Events_ID anId = SketchPlugin_MacroArcReentrantMessage::eventId();
+ std::shared_ptr<SketchPlugin_MacroArcReentrantMessage> aMessage = std::shared_ptr
+ <SketchPlugin_MacroArcReentrantMessage>(new SketchPlugin_MacroArcReentrantMessage(anId, 0));
+
+ std::string anEditType = string(EDIT_CIRCLE_TYPE())->value();
+ aMessage->setTypeOfCreation(!anEditType.empty() ? anEditType : aType);
+ aMessage->setCreatedFeature(aCircle);
+ Events_Loop::loop()->send(aMessage);
}
-void SketchPlugin_MacroCircle::createCircleByCenterAndPassed()
+std::string SketchPlugin_MacroCircle::processEvent(
+ const std::shared_ptr<Events_Message>& theMessage)
{
- // Create circle feature.
- std::shared_ptr<GeomAPI_Circ2d> aCircle = shapeByCenterAndPassed();
- FeaturePtr aCircleFeature = createCircleFeature(aCircle);
+ std::string aFilledAttributeName;
+ std::shared_ptr<SketchPlugin_MacroArcReentrantMessage> aReentrantMessage =
+ std::dynamic_pointer_cast<SketchPlugin_MacroArcReentrantMessage>(theMessage);
+ if (aReentrantMessage.get()) {
+ FeaturePtr aCreatedFeature = aReentrantMessage->createdFeature();
+ std::string aCircleType = aReentrantMessage->typeOfCreation();
+
+ string(CIRCLE_TYPE())->setValue(aCircleType);
+
+ aFilledAttributeName = CIRCLE_TYPE();
+ ObjectPtr anObject = aReentrantMessage->selectedObject();
+ AttributePtr anAttribute = aReentrantMessage->selectedAttribute();
+ std::shared_ptr<GeomAPI_Pnt2d> aClickedPoint = aReentrantMessage->clickedPoint();
+
+ if (aClickedPoint.get() && (anObject.get() || anAttribute.get())) {
+ std::string aReferenceAttributeName;
+ if (aCircleType == CIRCLE_TYPE_BY_CENTER_AND_PASSED_POINTS()) {
+ aFilledAttributeName = CENTER_POINT_ID();
+ aReferenceAttributeName = CENTER_POINT_REF_ID();
+ }
+ else {
+ aFilledAttributeName = FIRST_POINT_ID();
+ aReferenceAttributeName = FIRST_POINT_REF_ID();
+ }
+ // fill 2d point attribute
+ AttributePoint2DPtr aPointAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ attribute(aFilledAttributeName));
+ aPointAttr->setValue(aClickedPoint);
+ // fill reference attribute
+ AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+ attribute(aReferenceAttributeName));
+ if (aRefAttr.get()) {
+ if (anAttribute.get())
+ aRefAttr->setAttr(anAttribute);
+ else if (anObject.get()) {
+ // if presentation of previous reentrant macro arc is used, the object is invalid,
+ // we should use result of previous feature of the message(Arc)
+ if (!anObject->data()->isValid()) {
+ FeaturePtr aCreatedFeature = aReentrantMessage->createdFeature();
+ anObject = aCreatedFeature->lastResult();
+ }
+ aRefAttr->setObject(anObject);
+ }
+ }
+ }
+ Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
+ }
+ return aFilledAttributeName;
+}
+void SketchPlugin_MacroCircle::constraintsForCircleByCenterAndPassed(FeaturePtr theCircleFeature)
+{
// Create constraints.
- SketchPlugin_Tools::createConstraint(this,
- CENTER_POINT_REF_ID(),
- aCircleFeature->attribute(SketchPlugin_Circle::CENTER_ID()),
- ObjectPtr(),
- false);
- SketchPlugin_Tools::createConstraint(this,
- PASSED_POINT_REF_ID(),
- AttributePtr(),
- aCircleFeature->lastResult(),
- true);
+ SketchPlugin_Tools::createConstraint(
+ this, CENTER_POINT_REF_ID(),
+ theCircleFeature->attribute(SketchPlugin_Circle::CENTER_ID()),
+ ObjectPtr(), false);
+ SketchPlugin_Tools::createConstraint(
+ this, PASSED_POINT_REF_ID(), AttributePtr(),
+ theCircleFeature->lastResult(), true);
}
-void SketchPlugin_MacroCircle::createCircleByThreePoints()
+void SketchPlugin_MacroCircle::constraintsForCircleByThreePoints(FeaturePtr theCircleFeature)
{
std::string aPointRef[3] = { FIRST_POINT_REF_ID(),
SECOND_POINT_REF_ID(),
THIRD_POINT_REF_ID() };
- // Create circle feature.
- std::shared_ptr<GeomAPI_Circ2d> aCircle = shapeByThreePoints();
- FeaturePtr aCircleFeature = createCircleFeature(aCircle);
- ResultPtr aCircleResult = aCircleFeature->lastResult();
-
// Create constraints.
+ ResultPtr aCircleResult = theCircleFeature->lastResult();
for (int i = 0; i < 3; ++i)
SketchPlugin_Tools::createConstraint(this, aPointRef[i], AttributePtr(), aCircleResult, true);
}
-FeaturePtr SketchPlugin_MacroCircle::createCircleFeature(
- const std::shared_ptr<GeomAPI_Circ2d>& theCircle)
+FeaturePtr SketchPlugin_MacroCircle::createCircleFeature()
{
FeaturePtr aCircleFeature = sketch()->addFeature(SketchPlugin_Circle::ID());
- std::shared_ptr<GeomAPI_Pnt2d> aCenter = theCircle->center();
std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
- aCircleFeature->attribute(SketchPlugin_Circle::CENTER_ID()))->setValue(aCenter->x(),
- aCenter->y());
- aCircleFeature->real(SketchPlugin_Circle::RADIUS_ID())->setValue(theCircle->radius());
+ aCircleFeature->attribute(SketchPlugin_Circle::CENTER_ID()))->setValue(myCenter->x(),
+ myCenter->y());
+ aCircleFeature->real(SketchPlugin_Circle::RADIUS_ID())->setValue(myRadius);
aCircleFeature->boolean(SketchPlugin_Circle::AUXILIARY_ID())
->setValue(boolean(AUXILIARY_ID())->value());
aCircleFeature->execute();
return aCircleFeature;
}
-std::shared_ptr<GeomAPI_Circ2d> SketchPlugin_MacroCircle::shapeByCenterAndPassed()
+void SketchPlugin_MacroCircle::fillByCenterAndPassed()
{
AttributePtr aCenterAttr = attribute(CENTER_POINT_ID());
AttributePtr aPassedAttr = attribute(PASSED_POINT_ID());
if (!aCenterAttr->isInitialized() || !aPassedAttr->isInitialized())
- return std::shared_ptr<GeomAPI_Circ2d>();
+ return;
AttributeRefAttrPtr aPassedRef = refattr(PASSED_POINT_REF_ID());
// Calculate circle parameters
aPassedRef, aPassedAttr, aTangentCurve, aPassedPoint);
// Build a circle
- std::shared_ptr<GeomAPI_Circ2d> aCircle;
+ GeomAlgoAPI_Circ2dBuilder aCircBuilder(SketchPlugin_Sketch::plane(sketch()));
+ aCircBuilder.setCenter(aCenter);
if (aTangentCurve) {
- std::shared_ptr<GeomAPI_Ax3> anAxis = SketchPlugin_Sketch::plane(sketch());
- aCircle = std::shared_ptr<GeomAPI_Circ2d>(new GeomAPI_Circ2d(aCenter, aTangentCurve, anAxis));
+ aCircBuilder.addTangentCurve(aTangentCurve);
+
+ AttributePoint2DPtr aPassedPntAttr =
+ std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aPassedAttr);
+ if (aPassedPntAttr)
+ aCircBuilder.setClosestPoint(aPassedPntAttr->pnt());
} else
- aCircle = std::shared_ptr<GeomAPI_Circ2d>(new GeomAPI_Circ2d(aCenter, aPassedPoint));
- return aCircle;
+ aCircBuilder.addPassingPoint(aPassedPoint);
+
+ std::shared_ptr<GeomAPI_Circ2d> aCircle = aCircBuilder.circle();
+ if (aCircle) {
+ myCenter = aCircle->center();
+ myRadius = aCircle->radius();
+ }
}
-std::shared_ptr<GeomAPI_Circ2d> SketchPlugin_MacroCircle::shapeByThreePoints()
+void SketchPlugin_MacroCircle::fillByThreePoints()
{
std::string aPointAttr[3] = { FIRST_POINT_ID(),
SECOND_POINT_ID(),
std::string aPointRef[3] = { FIRST_POINT_REF_ID(),
SECOND_POINT_REF_ID(),
THIRD_POINT_REF_ID() };
- std::shared_ptr<GeomAPI_Interface> aPassedEntities[3];
+
+ GeomAlgoAPI_Circ2dBuilder aCircBuilder(SketchPlugin_Sketch::plane(sketch()));
+
for (int aPntIndex = 0; aPntIndex < 3; ++aPntIndex) {
AttributePtr aPassedAttr = attribute(aPointAttr[aPntIndex]);
if (!aPassedAttr->isInitialized())
aPassedRef, aPassedAttr, aTangentCurve, aPassedPoint);
if (aPassedPoint)
- aPassedEntities[aPntIndex] = aPassedPoint;
- else
- aPassedEntities[aPntIndex] = aTangentCurve;
+ aCircBuilder.addPassingPoint(aPassedPoint);
+ else {
+ aCircBuilder.addTangentCurve(aTangentCurve);
+ AttributePoint2DPtr aPassedPoint =
+ std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aPassedAttr);
+ if (aPassedPoint)
+ aCircBuilder.setClosestPoint(aPassedPoint->pnt());
+ }
}
- std::shared_ptr<GeomAPI_Ax3> anAxis = SketchPlugin_Sketch::plane(sketch());
- std::shared_ptr<GeomAPI_Circ2d> aCircle = std::shared_ptr<GeomAPI_Circ2d>(
- new GeomAPI_Circ2d(aPassedEntities[0], aPassedEntities[1], aPassedEntities[2], anAxis));
- if (!aCircle->implPtr<char>())
- return std::shared_ptr<GeomAPI_Circ2d>();
- return aCircle;
+ std::shared_ptr<GeomAPI_Circ2d> aCircle = aCircBuilder.circle();
+ if (aCircle) {
+ myCenter = aCircle->center();
+ myRadius = aCircle->radius();
+ }
}
-std::shared_ptr<GeomAPI_Circ2d> SketchPlugin_MacroCircle::shapeByTwoPassedPoints()
+void SketchPlugin_MacroCircle::fillByTwoPassedPoints()
{
std::string aPointAttr[2] = { FIRST_POINT_ID(),
SECOND_POINT_ID() };
std::string aPointRef[2] = { FIRST_POINT_REF_ID(),
SECOND_POINT_REF_ID() };
+
+ GeomAlgoAPI_Circ2dBuilder aCircBuilder(SketchPlugin_Sketch::plane(sketch()));
+
std::shared_ptr<GeomAPI_Pnt2d> aPassedPoints[2]; // there is possible only two passed points
- std::shared_ptr<GeomAPI_Interface> aPassedEntities[3];
+ bool hasTangentCurve = false;
int aPntIndex = 0;
for (; aPntIndex < 2; ++aPntIndex) {
AttributePtr aPassedAttr = attribute(aPointAttr[aPntIndex]);
aPassedRef, aPassedAttr, aTangentCurve, aPassedPoint);
if (aPassedPoint) {
- aPassedEntities[aPntIndex] = aPassedPoint;
+ aCircBuilder.addPassingPoint(aPassedPoint);
aPassedPoints[aPntIndex] = aPassedPoint;
} else {
- aPassedEntities[aPntIndex] = aTangentCurve;
+ hasTangentCurve = true;
+ aCircBuilder.addTangentCurve(aTangentCurve);
// if the circle is tangent to any curve,
// the third point will be initialized by the tangent point
- aPassedEntities[2] = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aPassedAttr)->pnt();
+ aCircBuilder.addPassingPoint(
+ std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aPassedAttr)->pnt());
}
}
if (aPntIndex <= 1)
- return std::shared_ptr<GeomAPI_Circ2d>();
+ return;
std::shared_ptr<GeomAPI_Circ2d> aCircle;
- if (aPassedEntities[2]) {
- std::shared_ptr<GeomAPI_Ax3> anAxis = SketchPlugin_Sketch::plane(sketch());
- aCircle = std::shared_ptr<GeomAPI_Circ2d>(
- new GeomAPI_Circ2d(aPassedEntities[0], aPassedEntities[1], aPassedEntities[2], anAxis));
- } else {
+
+ if (hasTangentCurve)
+ aCircle = aCircBuilder.circle();
+ else {
// the circle is defined by two points, calculate its parameters manually
std::shared_ptr<GeomAPI_Pnt2d> aCenter(new GeomAPI_Pnt2d(
(aPassedPoints[0]->x() + aPassedPoints[1]->x()) * 0.5,
(aPassedPoints[0]->y() + aPassedPoints[1]->y()) * 0.5));
aCircle = std::shared_ptr<GeomAPI_Circ2d>(new GeomAPI_Circ2d(aCenter, aPassedPoints[0]));
}
- if (!aCircle->implPtr<char>())
- return std::shared_ptr<GeomAPI_Circ2d>();
- return aCircle;
+
+ if (aCircle) {
+ myCenter = aCircle->center();
+ myRadius = aCircle->radius();
+ }
}
AISObjectPtr SketchPlugin_MacroCircle::getAISObject(AISObjectPtr thePrevious)
{
SketchPlugin_Sketch* aSketch = sketch();
- if(!aSketch) {
+ if(!aSketch || !myCenter || myRadius == 0) {
return AISObjectPtr();
}
- // Create circle on the sketch plane
- std::shared_ptr<GeomAPI_Circ2d> aCircleOnSketch;
- std::string aType = string(CIRCLE_TYPE())->value();
- if (aType == CIRCLE_TYPE_BY_CENTER_AND_PASSED_POINTS())
- aCircleOnSketch = shapeByCenterAndPassed();
- else if (aType == CIRCLE_TYPE_BY_THREE_POINTS()) {
- if (attribute(THIRD_POINT_ID())->isInitialized())
- aCircleOnSketch = shapeByThreePoints();
- else
- aCircleOnSketch = shapeByTwoPassedPoints();
- }
-
- if (!aCircleOnSketch)
- return AISObjectPtr();
-
- std::shared_ptr<GeomAPI_Pnt2d> aCenter2D = aCircleOnSketch->center();
- double aRadius = aCircleOnSketch->radius();
-
// Compute a circle in 3D view.
- std::shared_ptr<GeomAPI_Pnt> aCenter(aSketch->to3D(aCenter2D->x(), aCenter2D->y()));
+ std::shared_ptr<GeomAPI_Pnt> aCenter(aSketch->to3D(myCenter->x(), myCenter->y()));
std::shared_ptr<GeomDataAPI_Dir> aNDir =
std::dynamic_pointer_cast<GeomDataAPI_Dir>(
aSketch->data()->attribute(SketchPlugin_Sketch::NORM_ID()));
std::shared_ptr<GeomAPI_Dir> aNormal = aNDir->dir();
- GeomShapePtr aCircleShape = GeomAlgoAPI_EdgeBuilder::lineCircle(aCenter, aNormal, aRadius);
+ GeomShapePtr aCircleShape = GeomAlgoAPI_EdgeBuilder::lineCircle(aCenter, aNormal, myRadius);
GeomShapePtr aCenterPointShape = GeomAlgoAPI_PointBuilder::vertex(aCenter);
if(!aCircleShape.get() || !aCenterPointShape.get()) {
return AISObjectPtr();
SketchPlugin_Tools::resetAttribute(this, SECOND_POINT_REF_ID());
SketchPlugin_Tools::resetAttribute(this, THIRD_POINT_ID());
SketchPlugin_Tools::resetAttribute(this, THIRD_POINT_REF_ID());
- } else if(theID == CENTER_POINT_ID() || theID == PASSED_POINT_ID()) {
- std::shared_ptr<GeomDataAPI_Point2D> aCenterPointAttr =
- std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(CENTER_POINT_ID()));
- if(!aCenterPointAttr->isInitialized()) {
- return;
- }
- std::shared_ptr<GeomDataAPI_Point2D> aPassedPointAttr =
- std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(PASSED_POINT_ID()));
- if(!aPassedPointAttr->isInitialized()) {
- return;
- }
-
- aRadius = aCenterPointAttr->pnt()->distance(aPassedPointAttr->pnt());
- } else if(theID == FIRST_POINT_ID() || theID == SECOND_POINT_ID() || theID == THIRD_POINT_ID()) {
+ } else if(theID == CENTER_POINT_ID() || theID == PASSED_POINT_ID() ||
+ theID == CENTER_POINT_REF_ID() || theID == PASSED_POINT_REF_ID())
+ fillByCenterAndPassed();
+ else if(theID == FIRST_POINT_ID() || theID == FIRST_POINT_REF_ID() ||
+ theID == SECOND_POINT_ID() || theID == SECOND_POINT_REF_ID() ||
+ theID == THIRD_POINT_ID() || theID == THIRD_POINT_REF_ID()) {
std::shared_ptr<GeomAPI_Pnt2d> aPoints[3];
int aNbInitialized = 0;
for(int i = 1; i <= 3; ++i) {
aPoints[aNbInitialized++] = aCurPnt->pnt();
}
- std::shared_ptr<GeomAPI_Circ2d> aCircle;
if(aNbInitialized == 1)
return;
else if(aNbInitialized == 2)
- aCircle = shapeByTwoPassedPoints();
+ fillByTwoPassedPoints();
else
- aCircle = shapeByThreePoints();
- if (aCircle)
- aRadius = aCircle->radius();
+ fillByThreePoints();
}
AttributeDoublePtr aRadiusAttr = real(CIRCLE_RADIUS_ID());
bool aWasBlocked = data()->blockSendAttributeUpdated(true);
- aRadiusAttr->setValue(aRadius);
+ aRadiusAttr->setValue(myRadius);
data()->blockSendAttributeUpdated(aWasBlocked, false);
}
#ifndef SketchPlugin_MacroCircle_H_
#define SketchPlugin_MacroCircle_H_
+#include <ModelAPI_IReentrant.h>
+
#include "SketchPlugin.h"
#include "SketchPlugin_SketchEntity.h"
* \brief Feature for creation of the new circle in Sketch.
*/
class SketchPlugin_MacroCircle: public SketchPlugin_SketchEntity,
- public GeomAPI_IPresentable
+ public GeomAPI_IPresentable,
+ public ModelAPI_IReentrant
{
public:
/// Circle feature kind
return ID;
}
+ inline static const std::string& EDIT_CIRCLE_TYPE()
+ {
+ static const std::string ID("edit_circle_type");
+ return ID;
+ }
+
/// Creation method by center and passed point.
inline static const std::string& CIRCLE_TYPE_BY_CENTER_AND_PASSED_POINTS()
{
SKETCHPLUGIN_EXPORT virtual bool isPreviewNeeded() const {return false;};
+ /// Apply information of the message to current object. It fills reference object,
+ /// tangent type and tangent point refence in case of tangent arc
+ virtual std::string processEvent(const std::shared_ptr<Events_Message>& theMessage);
+
/// Use plugin manager for features creation
SketchPlugin_MacroCircle();
private:
- std::shared_ptr<GeomAPI_Circ2d> shapeByCenterAndPassed();
- std::shared_ptr<GeomAPI_Circ2d> shapeByThreePoints();
- /// Creates shape if only two of three points is initialized
- std::shared_ptr<GeomAPI_Circ2d> shapeByTwoPassedPoints();
+ void fillByCenterAndPassed();
+ void fillByThreePoints();
+ /// set fields if only two of three points is initialized
+ void fillByTwoPassedPoints();
- void createCircleByCenterAndPassed();
- void createCircleByThreePoints();
+ void constraintsForCircleByCenterAndPassed(FeaturePtr theCircleFeature);
+ void constraintsForCircleByThreePoints(FeaturePtr theCircleFeature);
- FeaturePtr createCircleFeature(const std::shared_ptr<GeomAPI_Circ2d>& theCircle);
+ FeaturePtr createCircleFeature();
+
+private:
+ std::shared_ptr<GeomAPI_Pnt2d> myCenter;
+ double myRadius;
};
#endif
#include <iostream>
#endif
+#define SKETCH_ENTITY_COLOR "225,0,0"
+#define SKETCH_EXTERNAL_COLOR "170,0,225"
+#define SKETCH_AUXILIARY_COLOR "0,85,0"
+#define SKETCH_OVERCONSTRAINT_COLOR "0,0,0"
+#define SKETCH_FULLY_CONSTRAINED_COLOR "0,150,0"
+
//#define SET_PLANES_COLOR_IN_PREFERENCES
// the only created instance of this plugin
"Sketch overconstraint color",
Config_Prop::Color, SKETCH_OVERCONSTRAINT_COLOR);
+ Config_PropManager::registerProp("Visualization", "sketch_fully_constrained_color",
+ "Sketch fully constrained color",
+ Config_Prop::Color, SKETCH_FULLY_CONSTRAINED_COLOR);
+
// register sketcher properties
#ifdef SET_PLANES_COLOR_IN_PREFERENCES
Config_PropManager::registerProp("Visualization", "yz_plane_color", "YZ plane color",
/// Coordinates of the point
inline static const std::string& COORD_ID()
{
- static const std::string MY_COORD_ID("PointCoordindates");
+ static const std::string MY_COORD_ID("PointCoordinates");
return MY_COORD_ID;
}
/// Returns the kind of a feature
}
// set as current also after it becomes sub to set correctly enabled for other sketch subs
document()->setCurrentFeature(aNew, false);
+
+ static Events_Loop* aLoop = Events_Loop::loop();
+ static Events_ID aDeleteEvent = aLoop->eventByName(EVENT_OBJECT_DELETED);
+ aLoop->flush(aDeleteEvent);
+
return aNew;
}
#include <Config_PropManager.h>
-#define SKETCH_ENTITY_COLOR "225,0,0"
-#define SKETCH_EXTERNAL_COLOR "170,0,225"
-#define SKETCH_AUXILIARY_COLOR "0,85,0"
-#define SKETCH_OVERCONSTRAINT_COLOR "0,0,0"
-
/**\class SketchPlugin_SketchEntity
* \ingroup Plugins
* \brief Sketch Entity for creation of the new feature in PartSet.
if (!theResult.get()) {
double aDeflection = Config_PropManager::real("Visualization", "construction_deflection");
thePrs->setDeflection(aDeflection);
- }
+ }
return isCustomized;
}
#include <SketchPlugin_MultiTranslation.h>
#include <SketchPlugin_Point.h>
+#include <ModelAPI_EventReentrantMessage.h>
+
#include <ModelAPI_Events.h>
#include <SketchPlugin_Line.h>
#include <SketchPlugin_Arc.h>
#include <cmath>
-#define DEBUG_TRIM
+//#define DEBUG_TRIM_METHODS
+//#define DEBUG_TRIM
+
#ifdef DEBUG_TRIM
#include <iostream>
#endif
+#ifdef DEBUG_TRIM_METHODS
+#include <iostream>
+#endif
+
static const double PI = 3.141592653589793238463;
static const std::string OPERATION_HIGHLIGHT_COLOR() { return "128, 0, 0"; }
const std::shared_ptr<GeomAPI_Pnt>& thePoint)
{
std::shared_ptr<GeomAPI_Pnt2d> aPoint;
+ if (!thePoint.get())
+ return aPoint;
AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
data()->attribute(SketchPlugin_Trim::SELECTED_OBJECT()));
void SketchPlugin_Trim::execute()
{
-#ifdef DEBUG_TRIM
- std::cout << "SketchPlugin_Trim::execute" << std::endl;
+#ifdef DEBUG_TRIM_METHODS
+ std::cout << "SketchPlugin_Trim::execute: " << data()->name() << std::endl;
#endif
SketchPlugin_Sketch* aSketch = sketch();
return;
FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
+ /// Remove reference of this feature to feature used in preview, it is not necessary anymore
+ /// as trim will be removed after execute
+ AttributeReferencePtr aPreviewObjectAttr =
+ std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
+ data()->attribute(SketchPlugin_Trim::PREVIEW_OBJECT()));
+
+ ObjectPtr aPreviewObject = aPreviewObjectAttr->value();
+ AttributePoint2DPtr aPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ data()->attribute(PREVIEW_POINT()));
+ std::shared_ptr<GeomAPI_Pnt2d> aPreviewPnt2d = aPoint->pnt();
+ // nullify pointer of preview attribute
+ aPreviewObjectAttr->setValue(ResultPtr());
+
+ bool anIsEqualPreviewAndSelected = aPreviewObject == aBaseObject;
+
/// points of trim
std::shared_ptr<GeomAPI_Pnt> aStartShapePoint, aLastShapePoint;
#ifdef DEBUG_TRIM
findShapePoints(SELECTED_OBJECT(), SELECTED_POINT(), aStartShapePoint, aLastShapePoint);
std::shared_ptr<GeomAPI_Pnt2d> aStartShapePoint2d = convertPoint(aStartShapePoint);
-
std::shared_ptr<GeomAPI_Pnt2d> aLastShapePoint2d = convertPoint(aLastShapePoint);
std::set<FeaturePtr> aFeaturesToDelete;
std::map<AttributePtr, std::list<AttributePtr> > aBaseRefAttributes;
std::list<AttributePtr> aRefsToFeature;
getRefAttributes(aBaseFeature, aBaseRefAttributes, aRefsToFeature);
-
+#ifdef DEBUG_TRIM
+ std::cout << "---- getRefAttributes ----" << std::endl;
+ std::map<AttributePtr, std::list<AttributePtr> >::const_iterator
+ aRefIt = aBaseRefAttributes.begin(), aRefLast = aBaseRefAttributes.end();
+ std::cout << std::endl << "References to attributes of base feature [" <<
+ aBaseRefAttributes.size() << "]" << std::endl;
+ for (; aRefIt != aRefLast; aRefIt++) {
+ AttributePtr aBaseAttr = aRefIt->first;
+ std::list<AttributePtr> aRefAttributes = aRefIt->second;
+ std::string aRefsInfo;
+ std::list<AttributePtr>::const_iterator aRefAttrIt = aRefAttributes.begin(),
+ aRefAttrLast = aRefAttributes.end();
+ for (; aRefAttrIt != aRefAttrLast; aRefAttrIt++) {
+ if (!aRefsInfo.empty())
+ aRefsInfo.append(",");
+ AttributePtr aRAttr = *aRefAttrIt;
+ aRefsInfo.append(aRAttr->id());
+ FeaturePtr aRFeature = ModelAPI_Feature::feature(aRAttr->owner());
+ aRefsInfo.append("(" + aRFeature->name() + ") ");
+ }
+ std::shared_ptr<GeomDataAPI_Point2D> aPointAttr =
+ std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aBaseAttr);
+ std::cout << aPointAttr->id().c_str() <<
+ ": " << "[" << aRefAttributes.size() << "] " << aRefsInfo << std::endl;
+ }
+ std::cout << std::endl;
+ std::cout << std::endl << "References to base feature [" <<
+ aRefsToFeature.size() << "]" << std::endl;
+ std::list<AttributePtr>::const_iterator aRefAttrIt = aRefsToFeature.begin(),
+ aRefAttrLast = aRefsToFeature.end();
+ std::string aRefsInfo;
+ for (; aRefAttrIt != aRefAttrLast; aRefAttrIt++) {
+ if (!aRefsInfo.empty())
+ aRefsInfo.append(",");
+ AttributePtr aRAttr = *aRefAttrIt;
+ aRefsInfo.append(aRAttr->id());
+ FeaturePtr aRFeature = ModelAPI_Feature::feature(aRAttr->owner());
+ aRefsInfo.append("(" + aRFeature->name() + ") ");
+ }
+ std::cout << "[" << aRefsToFeature.size() << "] " << aRefsInfo << std::endl;
+ std::cout << "---- getRefAttributes:end ----" << std::endl;
+#endif
// coincidence to result points
// find coincidences to the base object, it should be used when attribute is found
// in myObjectToPoints
- std::map<AttributePtr, FeaturePtr> aCoincidencesToBaseFeature;
- getCoincidencesToObject(aBaseObject, aCoincidencesToBaseFeature);
+ //std::map<AttributePtr, FeaturePtr> aCoincidencesToBaseFeature;
+ //getCoincidencesToObject(aBaseObject, aCoincidencesToBaseFeature);
std::set<AttributePoint2DPtr> aFurtherCoincidences;
std::set<std::pair<AttributePtr, AttributePtr>> aModifiedAttributes;
const std::string& aKind = aBaseFeature->getKind();
- FeaturePtr aReplacingFeature;
+ FeaturePtr aReplacingFeature, aNewFeature;
if (aKind == SketchPlugin_Circle::ID()) {
aReplacingFeature = trimCircle(aStartShapePoint2d, aLastShapePoint2d,
aFurtherCoincidences, aModifiedAttributes);
// otherwise Trim feature will be removed with the circle before
// this operation is finished
aBaseObjectAttr->setObject(ResultPtr());
-
- AttributeReferencePtr aPreviewObjectAttr =
- std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
- data()->attribute(SketchPlugin_Trim::PREVIEW_OBJECT()));
- aPreviewObjectAttr->setObject(ResultPtr());
-
}
else if (aKind == SketchPlugin_Line::ID()) {
- trimLine(aStartShapePoint2d, aLastShapePoint2d,
- aFurtherCoincidences, aModifiedAttributes);
+ aNewFeature = trimLine(aStartShapePoint2d, aLastShapePoint2d, aBaseRefAttributes,
+ aFurtherCoincidences, aModifiedAttributes);
}
else if (aKind == SketchPlugin_Arc::ID()) {
- trimArc(aStartShapePoint2d, aLastShapePoint2d,
- aFurtherCoincidences, aModifiedAttributes);
+ aNewFeature = trimArc(aStartShapePoint2d, aLastShapePoint2d, aBaseRefAttributes,
+ aFurtherCoincidences, aModifiedAttributes);
}
// constraints to end points of trim feature
std::shared_ptr<GeomAPI_Pnt2d> aPoint2d = aPointAttribute->pnt();
#ifdef DEBUG_TRIM
- std::cout << "<compare Points> => "
+ std::cout << "<compare Points> => " << std::endl
<< "aPoint2d: [" << aPoint2d->x() << ", " << aPoint2d->y() << "]" << std::endl;
if (aStartShapePoint2d.get())
std::cout << "Start Point: [" << aStartShapePoint2d->x() << ", " << aStartShapePoint2d->y()
break;
}
}
- /*const std::list<AttributePoint2DPtr >& anAttributes = anInfo.first;
- for (std::list<AttributePoint2DPtr>::const_iterator anAttrIt = anAttributes.begin();
- anAttrIt != anAttributes.end(); anAttrIt++) {
- AttributePtr anAttribute = *anAttrIt;
- if (aCoincidencesToBaseFeature.find(anAttribute) != aCoincidencesToBaseFeature.end())
- {
- FeaturePtr anAttrFeature = aCoincidencesToBaseFeature.at(anAttribute);
- AttributePtr anOtherAttribute;
- if (std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>
- (anAttrFeature->attribute(SketchPlugin_Constraint::ENTITY_A()))->attr() == anAttribute)
- anOtherAttribute = anAttrFeature->attribute(SketchPlugin_Constraint::ENTITY_B());
- else if (std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>
- (anAttrFeature->attribute(SketchPlugin_Constraint::ENTITY_B()))->attr() == anAttribute)
- anOtherAttribute = anAttrFeature->attribute(SketchPlugin_Constraint::ENTITY_A());
- else
- continue;
- AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>
- (anOtherAttribute);
- if (aRefAttr.get())
- aRefAttr->setAttr(aPointAttribute);
- }
- }
- */
const std::list<ObjectPtr>& anObjects = anInfo.second;
for (std::list<ObjectPtr>::const_iterator anObjectIt = anObjects.begin();
anObjectIt != anObjects.end(); anObjectIt++) {
aLast = aRefsToFeature.end();
anIt != aLast; anIt++) {
AttributePtr anAttribute = *anIt;
+
+ //if (replaceCoincidenceAttribute(anAttribute, aModifiedAttributes))
+ // continue;
+
if (setCoincidenceToAttribute(anAttribute, aFurtherCoincidences))
continue;
if (aReplacingResult.get()) {
- AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(anAttribute);
+ AttributeRefAttrPtr aRefAttr =
+ std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(anAttribute);
if (aRefAttr.get())
aRefAttr->setObject(aReplacingResult);
else {
}
}
+ updateRefAttConstraints(aBaseRefAttributes, aModifiedAttributes, aFeaturesToDelete);
+
// Wait all constraints being created, then send update events
static Events_ID anUpdateEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED);
bool isUpdateFlushed = Events_Loop::loop()->isFlushed(anUpdateEvent);
if (isUpdateFlushed)
Events_Loop::loop()->setFlushed(anUpdateEvent, false);
- updateRefAttConstraints(aBaseRefAttributes, aModifiedAttributes, aFeaturesToDelete);
-
// delete constraints
#ifdef DEBUG_TRIM
- std::cout << "remove features and references:" << std::endl;
- std::set<FeaturePtr>::const_iterator aDIt = aFeaturesToDelete.begin(),
- aDLast = aFeaturesToDelete.end();
- for (; aDIt != aDLast; aDIt++) {
- //std::cout << getFeatureInfo(*aDIt, false) << std::endl;
- //std::cout << std::endl;
+ if (aFeaturesToDelete.size() > 0) {
+ std::cout << "after SPlit: removeFeaturesAndReferences: " << std::endl;
+ std::string aValue;
+ for (std::set<FeaturePtr>::const_iterator anIt = aFeaturesToDelete.begin();
+ anIt != aFeaturesToDelete.end(); anIt++) {
+ FeaturePtr aFeature = *anIt;
+ std::cout << aFeature->data()->name() << std::endl;
+ }
}
#endif
ModelAPI_Tools::removeFeaturesAndReferences(aFeaturesToDelete);
Events_Loop::loop()->setFlushed(anUpdateEvent, true);
}
+ if (anIsEqualPreviewAndSelected) {
+ // equal preview and selected objects
+ // nothing to do if the preview and selected objects are different
+ if (aReplacingResult.get()) { // base object was removed
+ aPreviewObject = aReplacingResult;
+ //aMessage->setSelectedObject(aReplacingResult);
+
+ GeomShapePtr aSelectedShape = aReplacingResult->shape();
+ std::shared_ptr<GeomAPI_Pnt> aPreviewPnt = sketch()->to3D(aPreviewPnt2d->x(),
+ aPreviewPnt2d->y());
+ std::shared_ptr<GeomAPI_Pnt> aProjectedPoint;
+ if (ModelGeomAlgo_Point2D::isPointOnEdge(aSelectedShape, aPreviewPnt, aProjectedPoint)) {
+ bool aValue = true;
+ }
+ //aBaseShape = aShape;
+
+#ifdef DEBUG_TRIM_METHODS
+ if (!aSelectedShape.get())
+ std::cout << "Set empty selected object" << std::endl;
+ else
+ std::cout << "Set shape with ShapeType: " << aSelectedShape->shapeTypeStr() << std::endl;
+#endif
+ bool aValue = true;
+ }
+ else {
+ aPreviewObject = ObjectPtr();
+
+ aBaseFeature->execute(); // should recompute shapes of result to do not check obsolete one
+ aBaseObject = getFeatureResult(aBaseFeature);
+ std::shared_ptr<GeomAPI_Pnt> aPreviewPnt = sketch()->to3D(aPreviewPnt2d->x(),
+ aPreviewPnt2d->y());
+ ResultPtr aBaseResult = std::dynamic_pointer_cast<ModelAPI_Result>(aBaseObject);
+ if (aBaseResult) {
+ GeomShapePtr aShape = aBaseResult->shape();
+ std::shared_ptr<GeomAPI_Pnt> aProjectedPoint;
+ if (ModelGeomAlgo_Point2D::isPointOnEdge(aShape, aPreviewPnt, aProjectedPoint))
+ aPreviewObject = aBaseResult;
+ }
+ if (!aPreviewObject.get() && aNewFeature.get()) {
+ ResultPtr aNewFeatureResult = getFeatureResult(aNewFeature);
+ if (aNewFeatureResult.get()) {
+ GeomShapePtr aShape = aNewFeatureResult->shape();
+ std::shared_ptr<GeomAPI_Pnt> aProjectedPoint;
+ if (ModelGeomAlgo_Point2D::isPointOnEdge(aShape, aPreviewPnt, aProjectedPoint))
+ aPreviewObject = aNewFeatureResult;
+ }
+ }
+ }
+ }
+ if (aPreviewObject.get()) {
+ std::shared_ptr<ModelAPI_EventReentrantMessage> aMessage = std::shared_ptr
+ <ModelAPI_EventReentrantMessage>(new ModelAPI_EventReentrantMessage(
+ ModelAPI_EventReentrantMessage::eventId(), 0));
+ aMessage->setSelectedObject(aPreviewObject);
+ Events_Loop::loop()->send(aMessage);
+ }
#ifdef DEBUG_TRIM
std::cout << "SketchPlugin_Trim::done" << std::endl;
#endif
}
+std::string SketchPlugin_Trim::processEvent(const std::shared_ptr<Events_Message>& theMessage)
+{
+#ifdef DEBUG_TRIM_METHODS
+ std::cout << "SketchPlugin_Trim::processEvent:" << data()->name() << std::endl;
+#endif
+
+ std::string aFilledAttributeName;
+
+ std::shared_ptr<ModelAPI_EventReentrantMessage> aMessage =
+ std::dynamic_pointer_cast<ModelAPI_EventReentrantMessage>(theMessage);
+ if (aMessage.get()) {
+ ObjectPtr anObject = aMessage->selectedObject();
+ std::shared_ptr<GeomAPI_Pnt2d> aPoint = aMessage->clickedPoint();
+
+ if (anObject.get() && aPoint.get()) {
+ std::shared_ptr<ModelAPI_AttributeReference> aRefSelectedAttr =
+ std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
+ data()->attribute(SketchPlugin_Trim::SELECTED_OBJECT()));
+ std::shared_ptr<ModelAPI_AttributeReference> aRefPreviewAttr =
+ std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
+ data()->attribute(SketchPlugin_Trim::PREVIEW_OBJECT()));
+ aRefSelectedAttr->setValue(anObject);
+ aRefPreviewAttr->setValue(anObject);
+
+ std::shared_ptr<GeomDataAPI_Point2D> aPointSelectedAttr =
+ std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ data()->attribute(SketchPlugin_Trim::SELECTED_POINT()));
+ std::shared_ptr<GeomDataAPI_Point2D> aPointPreviewAttr =
+ std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ data()->attribute(SketchPlugin_Trim::PREVIEW_POINT()));
+ aPointSelectedAttr->setValue(aPoint);
+ aPointPreviewAttr->setValue(aPoint);
+
+ Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
+
+ GeomShapePtr aSelectedShape = getSubShape(SELECTED_OBJECT(), SELECTED_POINT());
+#ifdef DEBUG_TRIM_METHODS
+ if (!aSelectedShape.get())
+ std::cout << "Set empty selected object" << std::endl;
+ else
+ std::cout << "Set shape with ShapeType: " << aSelectedShape->shapeTypeStr() << std::endl;
+#endif
+ aFilledAttributeName = SketchPlugin_Trim::SELECTED_OBJECT();
+ }
+ }
+ return aFilledAttributeName;
+}
+
bool SketchPlugin_Trim::setCoincidenceToAttribute(const AttributePtr& theAttribute,
const std::set<AttributePoint2DPtr>& theFurtherCoincidences)
{
if (aPoint2d->isEqual(aRefPnt2d)) {
AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
theAttribute);
- /*if (theAttribute->id() == SketchPlugin_ConstraintCoincidence::ENTITY_A())
- aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
- aFeature->attribute(SketchPlugin_ConstraintCoincidence::ENTITY_B()));
- else if (theAttribute->id() == SketchPlugin_ConstraintCoincidence::ENTITY_B())
- aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
- aFeature->attribute(SketchPlugin_ConstraintCoincidence::ENTITY_A()));*/
if (aRefAttr.get()) {
aRefAttr->setAttr(aPointAttribute);
aFoundPoint = true;
}
}
}
- /*AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
- if (!aRefAttr.get())
- return false;
+ return aFoundPoint;
+}
- if (aRefAttr.get())
- aRefAttr->setObject(aReplacingResult);//continue;
- else {
- //AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anIt);
- AttributeReferencePtr aReferenceAttr =
- std::dynamic_pointer_cast<ModelAPI_AttributeReference>(anAttribute);
- }*/
+bool SketchPlugin_Trim::replaceCoincidenceAttribute(const AttributePtr& theCoincidenceAttribute,
+ const std::set<std::pair<AttributePtr, AttributePtr>>& theModifiedAttributes)
+{
+ FeaturePtr aCoincidenceFeature = ModelAPI_Feature::feature(theCoincidenceAttribute->owner());
+ if (aCoincidenceFeature->getKind() != SketchPlugin_ConstraintCoincidence::ID())
+ return false;
- return aFoundPoint;
+ AttributeRefAttrPtr aCAttrA = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+ aCoincidenceFeature->attribute(SketchPlugin_Constraint::ENTITY_A()));
+ AttributeRefAttrPtr aCAttrB = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+ aCoincidenceFeature->attribute(SketchPlugin_Constraint::ENTITY_B()));
+ AttributePtr aCAttrRefA = aCAttrA->attr();
+ AttributePtr aCAttrRefB = aCAttrB->attr();
+
+ bool isProcessed = false;
+ for (std::set<std::pair<AttributePtr, AttributePtr>>::const_iterator
+ anIt = theModifiedAttributes.begin(); anIt != theModifiedAttributes.end(); anIt++) {
+ AttributePtr anAttributeBefore = anIt->first;
+ if (anAttributeBefore == aCAttrRefA) {
+ aCAttrA->setAttr(anIt->second);
+ isProcessed = true;
+ }
+ if (anAttributeBefore == aCAttrRefB) {
+ aCAttrB->setAttr(anIt->second);
+ isProcessed = true;
+ }
+ }
+ return isProcessed;
}
bool SketchPlugin_Trim::isMacro() const
AISObjectPtr SketchPlugin_Trim::getAISObject(AISObjectPtr thePrevious)
{
+#ifdef DEBUG_TRIM_METHODS
+ std::cout << "SketchPlugin_Trim::getAISObject: " << data()->name() << std::endl;
+#endif
+
AISObjectPtr anAIS = thePrevious;
std::list<std::shared_ptr<GeomAPI_Shape> > aShapes;
}
}
-void SketchPlugin_Trim::getCoincidencesToObject(const ObjectPtr& theObject,
+/*void SketchPlugin_Trim::getCoincidencesToObject(const ObjectPtr& theObject,
std::map<AttributePtr, FeaturePtr>& theCoincidencesToBaseFeature)
{
const std::set<AttributePtr>& aRefsList = theObject->data()->refsToMe();
theCoincidencesToBaseFeature[anAttribute] = aRefFeature;
}
}
-}
+}*/
void SketchPlugin_Trim::updateRefAttConstraints(
const std::map<AttributePtr, std::list<AttributePtr> >& theBaseRefAttributes,
aRLast = aRefAttributes.end();
AttributePtr aNewAttribute = anIt->second;
- for (; aRefIt != aRLast; aRefIt++) {
- AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*aRefIt);
- if (aRefAttr.get()) {
- if (aNewAttribute.get())
- aRefAttr->setAttr(aNewAttribute);
- else
- theFeaturesToDelete.insert(ModelAPI_Feature::feature(aRefAttr->owner()));
-#ifdef DEBUG_TRIM
- //FeaturePtr aFeature = ModelAPI_Feature::feature(aRefAttr->owner());
- //std::cout << " -" << getFeatureInfo(aFeature) << std::endl;
-#endif
+ if (aNewAttribute.get()) {
+ for (; aRefIt != aRLast; aRefIt++) {
+ AttributeRefAttrPtr aRefAttr =
+ std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*aRefIt);
+ if (aRefAttr.get()) {
+ aRefAttr->setAttr(aNewAttribute);
+ }
}
}
}
}
-void SketchPlugin_Trim::trimLine(const std::shared_ptr<GeomAPI_Pnt2d>& theStartShapePoint,
- const std::shared_ptr<GeomAPI_Pnt2d>& theLastShapePoint,
- std::set<AttributePoint2DPtr>& thePoints,
+void SketchPlugin_Trim::removeReferencesToAttribute(const AttributePtr& theAttribute,
+ std::map<AttributePtr, std::list<AttributePtr> >& theBaseRefAttributes)
+{
+ /// not found in references
+ if (theBaseRefAttributes.find(theAttribute) == theBaseRefAttributes.end())
+ return;
+
+ std::list<AttributePtr> aRefAttributes = theBaseRefAttributes.at(theAttribute);
+ std::list<AttributePtr>::const_iterator aRefIt = aRefAttributes.begin(),
+ aRLast = aRefAttributes.end();
+
+ std::set<FeaturePtr> aFeaturesToDelete;
+ for (; aRefIt != aRLast; aRefIt++) {
+ AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*aRefIt);
+ if (aRefAttr.get()) {
+ aFeaturesToDelete.insert(ModelAPI_Feature::feature(aRefAttr->owner()));
+ }
+ }
+
+#ifdef DEBUG_TRIM
+ // delete constraints
+ if (aFeaturesToDelete.size() > 0) {
+ std::cout << "removeReferencesToAttribute: " << std::endl;
+ std::string aValue;
+ for (std::set<FeaturePtr>::const_iterator anIt = aFeaturesToDelete.begin();
+ anIt != aFeaturesToDelete.end(); anIt++) {
+ FeaturePtr aFeature = *anIt;
+ std::cout << aFeature->data()->name() << std::endl;
+ }
+ }
+#endif
+ ModelAPI_Tools::removeFeaturesAndReferences(aFeaturesToDelete);
+ Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_DELETED));
+}
+
+FeaturePtr SketchPlugin_Trim::trimLine(const std::shared_ptr<GeomAPI_Pnt2d>& theStartShapePoint,
+ const std::shared_ptr<GeomAPI_Pnt2d>& theLastShapePoint,
+ std::map<AttributePtr, std::list<AttributePtr> >& theBaseRefAttributes,
+ std::set<AttributePoint2DPtr>& thePoints,
std::set<std::pair<AttributePtr, AttributePtr>>& theModifiedAttributes)
{
+ FeaturePtr anNewFeature;
+
// Check the base objects are initialized.
AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
data()->attribute(SketchPlugin_Trim::SELECTED_OBJECT()));
else
aPoint = aStartShapePoint.get() ? aStartShapePoint : aLastShapePoint;
+ // it is important to delete references before the feature modification because
+ // if deletion will be after the feature modification, solver returns the feature back
+ removeReferencesToAttribute(aBaseFeature->attribute(aModifiedAttribute),
+ theBaseRefAttributes);
+
fillPointAttribute(aBaseFeature->attribute(aModifiedAttribute), aPoint);
- theModifiedAttributes.insert(
- std::make_pair(aBaseFeature->attribute(aModifiedAttribute), AttributePtr()));
+ //theModifiedAttributes.insert(
+ // std::make_pair(aBaseFeature->attribute(aModifiedAttribute), AttributePtr()));
thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
(aBaseFeature->attribute(aModifiedAttribute)));
// result is two lines: start line point - start shape point,
// last shape point - last line point
// create second line
- FeaturePtr anNewFeature = createLineFeature(aBaseFeature, aLastShapePoint, aLastFeaturePoint);
+ anNewFeature = createLineFeature(aBaseFeature, aLastShapePoint, aLastFeaturePoint);
thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
(anNewFeature->attribute(SketchPlugin_Line::START_ID())));
getFeatureResult(anNewFeature));
}
+ return anNewFeature;
}
-void SketchPlugin_Trim::trimArc(const std::shared_ptr<GeomAPI_Pnt2d>& theStartShapePoint,
- const std::shared_ptr<GeomAPI_Pnt2d>& theLastShapePoint,
- std::set<AttributePoint2DPtr>& thePoints,
+FeaturePtr SketchPlugin_Trim::trimArc(const std::shared_ptr<GeomAPI_Pnt2d>& theStartShapePoint,
+ const std::shared_ptr<GeomAPI_Pnt2d>& theLastShapePoint,
+ std::map<AttributePtr, std::list<AttributePtr> >& theBaseRefAttributes,
+ std::set<AttributePoint2DPtr>& thePoints,
std::set<std::pair<AttributePtr, AttributePtr>>& theModifiedAttributes)
{
+ FeaturePtr anNewFeature;
// Check the base objects are initialized.
AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
data()->attribute(SketchPlugin_Trim::SELECTED_OBJECT()));
#ifdef DEBUG_TRIM
std::cout << "Arranged points (to build split between 1st and 2nd points:" << std::endl;
if (aStartShapePoint.get())
- std::cout << "Start point: [" << aStartShapePoint->x() << ", " <<
+ std::cout << "Start shape point: [" << aStartShapePoint->x() << ", " <<
aStartShapePoint->y() << "]" << std::endl;
- std::cout << "1st point: [" << aStartArcPoint->x() << ", " <<
+ std::cout << "Start arc attribute point: [" << aStartArcPoint->x() << ", " <<
aStartArcPoint->y() << "]" << std::endl;
if (aLastShapePoint.get())
- std::cout << "2st point: [" << aLastShapePoint->x() << ", " <<
+ std::cout << "Last shape point: [" << aLastShapePoint->x() << ", " <<
aLastShapePoint->y() << "]" << std::endl;
- std::cout << "End point: [" << aLastArcPoint->x() << ", " <<
+ std::cout << "Last arc attribute point: [" << aLastArcPoint->x() << ", " <<
aLastArcPoint->y() << "]" << std::endl;
#endif
else
aPoint = aStartShapePoint.get() ? aStartShapePoint : aLastShapePoint;
+ removeReferencesToAttribute(aBaseFeature->attribute(aModifiedAttribute),
+ theBaseRefAttributes);
+
fillPointAttribute(aBaseFeature->attribute(aModifiedAttribute), aPoint);
- theModifiedAttributes.insert(
- std::make_pair(aBaseFeature->attribute(aModifiedAttribute), AttributePtr()));
thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
(aBaseFeature->attribute(aModifiedAttribute)));
else {
// result is two arcs: start arc point - start shape point, last shape point - last arc point
// create second arc
- FeaturePtr anArcFeature = createArcFeature(aBaseFeature, aLastShapePoint, aLastArcPoint);
+ anNewFeature = createArcFeature(aBaseFeature, aLastShapePoint, aLastArcPoint);
thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
- (anArcFeature->attribute(SketchPlugin_Arc::START_ID())));
+ (anNewFeature->attribute(SketchPlugin_Arc::START_ID())));
std::string aModifiedAttribute = SketchPlugin_Arc::END_ID();
theModifiedAttributes.insert(
std::make_pair(aBaseFeature->attribute(aModifiedAttribute),
- anArcFeature->attribute(SketchPlugin_Arc::END_ID())));
+ anNewFeature->attribute(SketchPlugin_Arc::END_ID())));
// modify base arc
fillPointAttribute(aBaseFeature->attribute(aModifiedAttribute), aStartShapePoint);
(aBaseFeature->attribute(aModifiedAttribute)));
// equal Radius constraint for arcs
- anArcFeature->execute(); // we need the created arc result to set equal constraint
+ anNewFeature->execute(); // we need the created arc result to set equal constraint
createConstraintForObjects(SketchPlugin_ConstraintEqual::ID(),
getFeatureResult(aBaseFeature),
- getFeatureResult(anArcFeature));
+ getFeatureResult(anNewFeature));
// coincident centers constraint
createConstraint(SketchPlugin_ConstraintCoincidence::ID(),
aBaseFeature->attribute(SketchPlugin_Arc::CENTER_ID()),
- anArcFeature->attribute(SketchPlugin_Arc::CENTER_ID()));
+ anNewFeature->attribute(SketchPlugin_Arc::CENTER_ID()));
+
+#ifdef DEBUG_TRIM
+ std::cout << "Created arc on points:" << std::endl;
+ std::cout << "Start shape point: [" << aStartShapePoint->x() << ", " <<
+ aStartShapePoint->y() << "]" << std::endl;
+#endif
}
+ return anNewFeature;
}
FeaturePtr SketchPlugin_Trim::trimCircle(const std::shared_ptr<GeomAPI_Pnt2d>& theStartShapePoint,
//getFeaturePoints(aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase);
/// trim feature
- FeaturePtr anArcFeature = createArcFeature(aBaseFeature, theStartShapePoint, theLastShapePoint);
+ FeaturePtr anNewFeature = createArcFeature(aBaseFeature, theStartShapePoint, theLastShapePoint);
// arc created by trim of circle is always correct, that means that it is not inversed
- anArcFeature->boolean(SketchPlugin_Arc::REVERSED_ID())->setValue(false);
+ anNewFeature->boolean(SketchPlugin_Arc::REVERSED_ID())->setValue(false);
theModifiedAttributes.insert(
std::make_pair(aBaseFeature->attribute(SketchPlugin_Circle::CENTER_ID()),
- anArcFeature->attribute(SketchPlugin_Arc::CENTER_ID())));
+ anNewFeature->attribute(SketchPlugin_Arc::CENTER_ID())));
thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
- (anArcFeature->attribute(SketchPlugin_Arc::START_ID())));
+ (anNewFeature->attribute(SketchPlugin_Arc::START_ID())));
thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
- (anArcFeature->attribute(SketchPlugin_Arc::END_ID())));
+ (anNewFeature->attribute(SketchPlugin_Arc::END_ID())));
- return anArcFeature;
+ return anNewFeature;
}
void SketchPlugin_Trim::arrangePointsOnLine(const AttributePoint2DPtr& theStartPointAttr,
aModifiedAttribute->setValue(thePoint);
#ifdef DEBUG_TRIM
- std::cout << "<fillPointAttribute> => Pnt2d - [" << thePoint->x() << ", "
- << thePoint->y() << "]" << std::endl;
+ FeaturePtr aFeature = ModelAPI_Feature::feature(theModifiedAttribute->owner());
+ std::cout << "<fillPointAttribute[" << aFeature->data()->name() << ": " <<
+ theModifiedAttribute->id() <<
+ "]> => Pnt2d - [" << thePoint->x() << ", " << thePoint->y() << "]" << std::endl;
#endif
}
}
const std::shared_ptr<GeomAPI_Pnt2d>& theFirstPoint,
const std::shared_ptr<GeomAPI_Pnt2d>& theSecondPoint)
{
+#ifdef DEBUG_TRIM
+ std::cout << "---- createLineFeature ---" << std::endl;
+#endif
+
FeaturePtr aFeature;
SketchPlugin_Sketch* aSketch = sketch();
if (!aSketch || !theBaseFeature.get())
aFeature->execute(); // to obtain result
+#ifdef DEBUG_TRIM
+ std::cout << "---- createLineFeature:end ---" << std::endl;
+#endif
+
return aFeature;
}
if (aCenterAttributeId.empty())
return aFeature;
+#ifdef DEBUG_TRIM
+ std::cout << "---- createArcFeature ---" << std::endl;
+#endif
+
aFeature = aSketch->addFeature(SketchPlugin_Arc::ID());
// update fillet arc: make the arc correct for sure, so, it is not needed to process
// the "attribute updated"
//aFeature->execute(); // to obtain result
aFeature->data()->blockSendAttributeUpdated(aWasBlocked);
+ #ifdef DEBUG_TRIM
+ std::cout << "---- createArcFeature:end ---" << std::endl;
+ #endif
+
return aFeature;
}
#ifndef SketchPlugin_Trim_H_
#define SketchPlugin_Trim_H_
+#include <ModelAPI_IReentrant.h>
+
#include "SketchPlugin.h"
-#include <SketchPlugin_Sketch.h>
#include "SketchPlugin_ConstraintBase.h"
+#include <SketchPlugin_Sketch.h>
class GeomDataAPI_Point2D;
class ModelAPI_Feature;
* \ingroup Plugins
* \brief Feature for creation of a new constraint trimming object. Entities for split:
*/
-class SketchPlugin_Trim : public SketchPlugin_Feature, public GeomAPI_IPresentable
+class SketchPlugin_Trim : public SketchPlugin_Feature, public GeomAPI_IPresentable,
+ public ModelAPI_IReentrant
{
public:
/// Split constraint kind
/// Moves the feature : Empty
SKETCHPLUGIN_EXPORT virtual void move(const double theDeltaX, const double theDeltaY) {};
- bool setCoincidenceToAttribute(const AttributePtr& theAttribute,
- const std::set<std::shared_ptr<GeomDataAPI_Point2D> >& theFurtherCoincidences);
+ /// Apply information of the message to current object. It fills selected point and object
+ virtual std::string processEvent(const std::shared_ptr<Events_Message>& theMessage);
typedef std::map<std::shared_ptr<GeomAPI_Pnt>,
std::pair<std::list<std::shared_ptr<GeomDataAPI_Point2D> >,
std::map<std::shared_ptr<ModelAPI_Object>, PointToRefsMap>& theObjectToPoints);
private:
+ bool setCoincidenceToAttribute(const AttributePtr& theAttribute,
+ const std::set<std::shared_ptr<GeomDataAPI_Point2D> >& theFurtherCoincidences);
+
+ bool replaceCoincidenceAttribute(const AttributePtr& theCoincidenceAttribute,
+ const std::set<std::pair<AttributePtr, AttributePtr>>& theModifiedAttributes);
+
GeomShapePtr getSubShape(const std::string& theObjectAttributeId,
const std::string& thePointAttributeId);
/// by the coincident attribute
/// \param theObject an investigated object
/// \param theCoincidencesToBaseFeature a container of list of referenced attributes
- void getCoincidencesToObject(const std::shared_ptr<ModelAPI_Object>& theObject,
- std::map<AttributePtr, FeaturePtr>& theCoincidencesToBaseFeature);
+ //void getCoincidencesToObject(const std::shared_ptr<ModelAPI_Object>& theObject,
+ // std::map<AttributePtr, FeaturePtr>& theCoincidencesToBaseFeature);
/// Move constraints from attribute of base feature to attribute after modification
/// \param theBaseRefAttributes container of references to the attributes of base feature
const std::set<std::pair<AttributePtr, AttributePtr> >& theModifiedAttributes,
std::set<std::shared_ptr<ModelAPI_Feature>>& theFeaturesToDelete);
+ /// Remove references constraints from attribute of base feature refer to the given attribute
+ /// \param theAttribute an attribute
+ /// \param theModifiedAttributes modifiable container of attributes
+ void removeReferencesToAttribute(const AttributePtr& theAttribute,
+ std::map<AttributePtr, std::list<AttributePtr> >& theBaseRefAttributes);
+
/// Make the base object is splitted by the point attributes
- /// \param theSplitFeature a result split feature
- /// \param theBeforeFeature a feature between start point and the 1st point of split feature
- /// \param theAfterFeature a feature between last point of split feature and the end point
+ /// \param theBaseRefAttributes container of references to the attributes of base feature
/// \param thePoints a list of points where coincidences will be build
/// \param theModifiedAttributes a container of attribute on base
/// feature to attribute on new feature
- void trimLine(const std::shared_ptr<GeomAPI_Pnt2d>& theStartShapePoint,
+ /// \return new line if it was created
+ FeaturePtr trimLine(const std::shared_ptr<GeomAPI_Pnt2d>& theStartShapePoint,
const std::shared_ptr<GeomAPI_Pnt2d>& theLastShapePoint,
+ std::map<AttributePtr, std::list<AttributePtr> >& theBaseRefAttributes,
std::set<std::shared_ptr<GeomDataAPI_Point2D> >& thePoints,
std::set<std::pair<AttributePtr, AttributePtr>>& theModifiedAttributes);
/// Make the base object is splitted by the point attributes
- /// \param theSplitFeature a result split feature
- /// \param theBeforeFeature a feature between start point and the 1st point of split feature
- /// \param theAfterFeature a feature between last point of split feature and the end point
/// \param thePoints a list of points where coincidences will be build
- void trimArc(const std::shared_ptr<GeomAPI_Pnt2d>& theStartShapePoint,
+ /// \return new line if it was created
+ FeaturePtr trimArc(const std::shared_ptr<GeomAPI_Pnt2d>& theStartShapePoint,
const std::shared_ptr<GeomAPI_Pnt2d>& theLastShapePoint,
+ std::map<AttributePtr, std::list<AttributePtr> >& theBaseRefAttributes,
std::set<std::shared_ptr<GeomDataAPI_Point2D> >& thePoints,
std::set<std::pair<AttributePtr, AttributePtr>>& theModifiedAttributes);
/// Make the base object is splitted by the point attributes
- /// \param theSplitFeature a result split feature
- /// \param theBeforeFeature a feature between start point and the 1st point of split feature
- /// \param theAfterFeature a feature between last point of split feature and the end point
/// \param thePoints a list of points where coincidences will be build
FeaturePtr trimCircle(const std::shared_ptr<GeomAPI_Pnt2d>& theStartShapePoint,
const std::shared_ptr<GeomAPI_Pnt2d>& theLastShapePoint,
AttributePtr aPreviewAttr = aTrimFeature->attribute(SketchPlugin_Trim::PREVIEW_OBJECT());
aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(aPreviewAttr);
aBaseObject = aBaseObjectAttr->value();
-
- //return aValid;
}
FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObject);
if (!aBaseFeature)
return aValid;
+ std::shared_ptr<SketchPlugin_Feature> aSketchFeature =
+ std::dynamic_pointer_cast<SketchPlugin_Feature>(aBaseFeature);
+ if (!aSketchFeature.get() || aSketchFeature->isCopy())
+ return aValid;
+
std::string aKind = aBaseFeature->getKind();
if (aKind != SketchPlugin_Line::ID() &&
aKind != SketchPlugin_Arc::ID() &&
aPoint3D = anEdge->line()->project(aPoint3D);
else if (anEdge->isCircle())
aPoint3D = anEdge->circle()->project(aPoint3D);
- aPoint = aSketch->to2D(aPoint3D);
+ if(aPoint3D)
+ aPoint = aSketch->to2D(aPoint3D);
}
}
} else {
return true;
}
- GeomShapePtr anArcShape = anArcFeature->getArcShape();
+ GeomShapePtr anArcShape = anArcFeature->getArcShape(false);
if(!anArcShape.get() || anArcShape->isNull()) {
return true;
if(aResult.get()) {
GeomShapePtr aShape = aResult->shape();
if(aShape.get() && !aShape->isNull()) {
- return GeomAlgoAPI_ShapeTools::isShapesIntersects(anArcShape, aShape);
+ GeomShapePtr anIntersection = anArcShape->intersect(aShape);
+ if(anIntersection.get() && !anIntersection->isNull()) {
+ return true;
+ }
}
}
{
GeomShapePtr aShape = (*anIt)->shape();
if(aShape.get() && !aShape->isNull()) {
- if(GeomAlgoAPI_ShapeTools::isShapesIntersects(anArcShape, aShape)) {
+ GeomShapePtr anIntersection = anArcShape->intersect(aShape);
+ if(anIntersection.get() && !anIntersection->isNull()) {
return true;
}
}
<context>
<name>SketchMacroCircle:Model_FeatureValidator</name>
<message>
- <source>Attribute "CircleCenter" is not initialized.</source>
+ <source>Attribute "circle_center" is not initialized.</source>
<translation>A center point is not selected</translation>
</message>
</context>
<context>
<name>SketchMacroCircle:CircleCenter</name>
<message>
- <source>Attribute "CircleCenter" is locked by modification value in the viewer.</source>
+ <source>Attribute "circle_center" is locked by modification value in the viewer.</source>
<translation>Select a center point</translation>
</message>
</context>
<context>
<name>SketchMacroCircle:CircleRadius</name>
<message>
- <source>Attribute "CircleRadius" is locked by modification value in the viewer.</source>
+ <source>Attribute "circle_radius" is locked by modification value in the viewer.</source>
<translation>Select a radius distance</translation>
</message>
</context>
<context>
<name>SketchMacroCircle:Model_FeatureValidator</name>
<message>
- <source>Attribute "CircleRadius" is not initialized.</source>
+ <source>Attribute "circle_radius" is not initialized.</source>
<translation>Set the circle radius</translation>
</message>
</context>
<context>
<name>SketchPoint:Model_FeatureValidator</name>
<message>
- <source>Attribute "PointCoordindates" is not initialized.</source>
+ <source>Attribute "PointCoordinates" is not initialized.</source>
<translation>Point is not defined</translation>
</message>
</context>
<context>
- <name>SketchPoint:PointCoordindates</name>
+ <name>SketchPoint:PointCoordinates</name>
<message>
- <source>Attribute "PointCoordindates" is locked by modification value in the viewer.</source>
+ <source>Attribute "PointCoordinates" is locked by modification value in the viewer.</source>
<translation>Select a point</translation>
</message>
</context>
<context>
<name>SketchArc:ArcCenter</name>
<message>
- <source>Attribute "ArcCenter" is locked by modification value in the viewer.</source>
+ <source>Attribute "center_point" is locked by modification value in the viewer.</source>
<translation>Select a center point</translation>
</message>
</context>
<context>
<name>SketchArc:ArcCenter</name>
<message>
- <source>Attribute "ArcCenter" is not initialized.</source>
+ <source>Attribute "center_point" is not initialized.</source>
<translation>Center point is not defined</translation>
</message>
</context>
<context>
<name>SketchArc:Model_FeatureValidator</name>
<message>
- <source>Attribute "ArcCenter" is not initialized.</source>
+ <source>Attribute "center_point" is not initialized.</source>
<translation>Select an arc center</translation>
</message>
</context>
<context>
<name>SketchArc:Model_FeatureValidator:ArcStartPoint</name>
<message>
- <source>Attribute "ArcStartPoint" is not initialized.</source>
+ <source>Attribute "start_point" is not initialized.</source>
<translation>Select an arc start point</translation>
</message>
</context>
<context>
<name>SketchArc:Model_FeatureValidator</name>
<message>
- <source>Attribute "ArcEndPoint" is not initialized.</source>
+ <source>Attribute "end_point" is not initialized.</source>
<translation>Select an arc end point</translation>
</message>
</context>
from GeomDataAPI import *
from ModelAPI import *
import math
+from salome.shaper import model
aSession = ModelAPI_Session.get()
aDocument = aSession.moduleDocument()
#=========================================================================
aSession.startOperation()
aSketchArc = aSketchFeature.addFeature("SketchArc")
-anArcCentr = geomDataAPI_Point2D(aSketchArc.attribute("ArcCenter"))
+anArcCentr = geomDataAPI_Point2D(aSketchArc.attribute("center_point"))
anArcCentr.setValue(0., 0.)
-anArcStartPoint = geomDataAPI_Point2D(aSketchArc.attribute("ArcStartPoint"))
+anArcStartPoint = geomDataAPI_Point2D(aSketchArc.attribute("start_point"))
anArcStartPoint.setValue(0., 10.)
-anArcEndPoint = geomDataAPI_Point2D(aSketchArc.attribute("ArcEndPoint"))
+anArcEndPoint = geomDataAPI_Point2D(aSketchArc.attribute("end_point"))
anArcEndPoint.setValue(1., 10.)
aSession.finishOperation()
# the arc must be small, not near to the whole circle
aSession.startOperation()
anArcEndPoint.setValue(10., 0.)
aSession.finishOperation()
-assert shapeToEdge(aSketchArc.lastResult().shape()).length() > 47.
-assert shapeToEdge(aSketchArc.lastResult().shape()).length() < 48.
+assert shapeToEdge(aSketchArc.lastResult().shape()).length() > 46.5
+assert shapeToEdge(aSketchArc.lastResult().shape()).length() < 47.5
aSession.startOperation()
anArcEndPoint.setValue(1., 10.)
aSession.finishOperation()
# check from the scratch that from initial state to counterclockwise position also works
aSession.startOperation()
aSketchArc = aSketchFeature.addFeature("SketchArc")
-anArcCentr = geomDataAPI_Point2D(aSketchArc.attribute("ArcCenter"))
+anArcCentr = geomDataAPI_Point2D(aSketchArc.attribute("center_point"))
anArcCentr.setValue(0., 0.)
-anArcStartPoint = geomDataAPI_Point2D(aSketchArc.attribute("ArcStartPoint"))
+anArcStartPoint = geomDataAPI_Point2D(aSketchArc.attribute("start_point"))
anArcStartPoint.setValue(0., 10.)
-anArcEndPoint = geomDataAPI_Point2D(aSketchArc.attribute("ArcEndPoint"))
+anArcEndPoint = geomDataAPI_Point2D(aSketchArc.attribute("end_point"))
anArcEndPoint.setValue(-1., 10.)
aSession.finishOperation()
# the arc must be small, not near to the whole circle
#=========================================================================
aSession.startOperation()
aSketchArc = aSketchFeature.addFeature("SketchArc")
-anArcCentr = geomDataAPI_Point2D(aSketchArc.attribute("ArcCenter"))
+anArcCentr = geomDataAPI_Point2D(aSketchArc.attribute("center_point"))
anArcCentr.setValue(0., 0.)
-anArcStartPoint = geomDataAPI_Point2D(aSketchArc.attribute("ArcStartPoint"))
+anArcStartPoint = geomDataAPI_Point2D(aSketchArc.attribute("start_point"))
anArcStartPoint.setValue(0., 10.)
-anArcEndPoint = geomDataAPI_Point2D(aSketchArc.attribute("ArcEndPoint"))
+anArcEndPoint = geomDataAPI_Point2D(aSketchArc.attribute("end_point"))
anArcEndPoint.setValue(10, 0.)
aSession.finishOperation()
-anInversed = aSketchArc.boolean("InversedArc").value()
+anInversed = aSketchArc.boolean("reversed").value()
for aCenterCoords in range(1, 20):
aSession.startOperation()
anArcCentr.setValue(aCenterCoords, aCenterCoords/2) # move center
aSession.finishOperation()
- assert aSketchArc.boolean("InversedArc").value() == anInversed
+ assert aSketchArc.boolean("reversed").value() == anInversed
for aCenterCoords in range(20, -20, -1):
aSession.startOperation()
anArcCentr.setValue(aCenterCoords, aCenterCoords/2) # move center
aSession.finishOperation()
- assert aSketchArc.boolean("InversedArc").value() == anInversed
+ assert aSketchArc.boolean("reversed").value() == anInversed
for aCenterCoords in range(-20, 20):
aSession.startOperation()
anArcCentr.setValue(aCenterCoords, aCenterCoords/2) # move center
aSession.finishOperation()
- assert aSketchArc.boolean("InversedArc").value() == anInversed
+ assert aSketchArc.boolean("reversed").value() == anInversed
#=========================================================================
-# Test that movement of start point of arc does not change central point
+# Test that movement of start point of arc does not break the arc
#=========================================================================
-TOL = 1.e-5
x = anArcCentr.x()
y = anArcCentr.y()
sx = anArcStartPoint.x()
aSession.startOperation()
anArcStartPoint.setValue(sx, sy+aDelta) # move start point
aSession.finishOperation()
- assert math.fabs(anArcCentr.x() - x) < TOL
- assert math.fabs(anArcCentr.y() - y) < TOL
+ model.assertSketchArc(aSketchArc)
for aDelta in range(20, -1, -1):
aSession.startOperation()
anArcStartPoint.setValue(sx, sy+aDelta) # move start point
aSession.finishOperation()
- assert math.fabs(anArcCentr.x() - x) < TOL
- assert math.fabs(anArcCentr.y() - y) < TOL
+ model.assertSketchArc(aSketchArc)
#=========================================================================
-# Test that movement of end point of arc does not change central point
+# Test that movement of end point of arc does not break the arc
#=========================================================================
x = anArcCentr.x()
y = anArcCentr.y()
aSession.startOperation()
anArcEndPoint.setValue(sx+aDelta, sy) # move end point
aSession.finishOperation()
- assert math.fabs(anArcCentr.x() - x) < TOL
- assert math.fabs(anArcCentr.y() - y) < TOL
+ model.assertSketchArc(aSketchArc)
for aDelta in range(20, -1, -1):
aSession.startOperation()
anArcEndPoint.setValue(sx+aDelta, sy) # move end point
aSession.finishOperation()
- assert math.fabs(anArcCentr.x() - x) < TOL
- assert math.fabs(anArcCentr.y() - y) < TOL
+ model.assertSketchArc(aSketchArc)
assert (math.fabs(aDirX * aVecY - aDirY * aVecX) <= TOLERANCE)
def checkPointOnCircle(point, circle):
- aCenter = geomDataAPI_Point2D(circle.attribute("CircleCenter"))
- aRadius = circle.real("CircleRadius").value()
+ aCenter = geomDataAPI_Point2D(circle.attribute("circle_center"))
+ aRadius = circle.real("circle_radius").value()
aDist = math.hypot(point.x() - aCenter.x(), point.y() - aCenter.y())
assert (math.fabs(aDist - aRadius) <= TOLERANCE)
def checkPointOnArc(point, arc):
- aStart = geomDataAPI_Point2D(arc.attribute("ArcStartPoint"))
- aCenter = geomDataAPI_Point2D(arc.attribute("ArcCenter"))
+ aStart = geomDataAPI_Point2D(arc.attribute("start_point"))
+ aCenter = geomDataAPI_Point2D(arc.attribute("center_point"))
aRadius = math.hypot(aStart.x() - aCenter.x(), aStart.y() - aCenter.y())
aDist = math.hypot(point.x() - aCenter.x(), point.y() - aCenter.y())
assert (math.fabs(aDist - aRadius) <= TOLERANCE)
#=========================================================================
aSession.startOperation()
aSketchArc = aSketchFeature.addFeature("SketchArc")
-anArcCentr = geomDataAPI_Point2D(aSketchArc.attribute("ArcCenter"))
-anArcStartPoint = geomDataAPI_Point2D(aSketchArc.attribute("ArcStartPoint"))
-anArcEndPoint = geomDataAPI_Point2D(aSketchArc.attribute("ArcEndPoint"))
+anArcCentr = geomDataAPI_Point2D(aSketchArc.attribute("center_point"))
+anArcStartPoint = geomDataAPI_Point2D(aSketchArc.attribute("start_point"))
+anArcEndPoint = geomDataAPI_Point2D(aSketchArc.attribute("end_point"))
anArcCentr.setValue(10., 10.)
anArcStartPoint.setValue(0., 50.)
anArcEndPoint.setValue(50., 0.)
aSession.startOperation()
# create circle with center coincident with origin
aSketchCircle = aSketchFeature.addFeature("SketchCircle")
-aCircleCenter = geomDataAPI_Point2D(aSketchCircle.attribute("CircleCenter"))
-aCircleRadius = aSketchCircle.real("CircleRadius")
+aCircleCenter = geomDataAPI_Point2D(aSketchCircle.attribute("circle_center"))
+aCircleRadius = aSketchCircle.real("circle_radius")
aCircleCenter.setValue(10., 10.)
aCircleRadius.setValue(25.)
aSession.finishOperation()
anOrigShape = anOrigRes.shape()
assert (anOrigShape)
anOrigin = aSketchFeature.addFeature("SketchPoint")
-anOriginCoord = geomDataAPI_Point2D(anOrigin.attribute("PointCoordindates"))
+anOriginCoord = geomDataAPI_Point2D(anOrigin.attribute("PointCoordinates"))
anOriginCoord.setValue(0., 0.)
anOrigin.selection("External").setValue(anOrigRes, anOrigShape)
aSession.finishOperation()
__updated__ = "2014-10-28"
-def distancePointPoint(pointA, pointB):
- """
- subroutine to calculate distance between two points
- result of calculated distance is has 10**-5 precision
- """
- xdiff = math.pow((pointA.x() - pointB.x()), 2)
- ydiff = math.pow((pointA.y() - pointB.y()), 2)
- return round(math.sqrt(xdiff + ydiff), 5)
-
def distancePointLine(point, line):
"""
subroutine to calculate distance between point and line
aSession.startOperation()
aSketchPoint = aSketchFeature.addFeature("SketchPoint")
aSketchPointCoords = geomDataAPI_Point2D(
- aSketchPoint.attribute("PointCoordindates"))
+ aSketchPoint.attribute("PointCoordinates"))
aSketchPointCoords.setValue(50., 50.)
aSketchLine = aSketchFeature.addFeature("SketchLine")
aLineAStartPoint = geomDataAPI_Point2D(aSketchLine.attribute("StartPoint"))
# Make a constraint to keep the distance
#=========================================================================
PT_PT_DIST = 25.
-aDist = distancePointPoint(aSketchPointCoords, aLineAStartPoint);
+aDist = model.distancePointPoint(aSketchPointCoords, aLineAStartPoint);
assert (aDist != PT_PT_DIST)
aSession.startOperation()
aConstraint = aSketchFeature.addFeature("SketchConstraintDistance")
aSession.startOperation()
aDistance.setValue(PT_PT_DIST)
aSession.finishOperation()
-assert (math.fabs(distancePointPoint(aSketchPointCoords, aLineAStartPoint) - PT_PT_DIST) < 1.e-10)
+assert (math.fabs(model.distancePointPoint(aSketchPointCoords, aLineAStartPoint) - PT_PT_DIST) < 1.e-10)
assert (model.dof(aSketchFeature) == 5)
#=========================================================================
# Move line, check that distance is constant
aLineAStartPoint.setValue(0., 40.)
aLineAEndPoint.setValue(100., 40.)
aSession.finishOperation()
-assert (math.fabs(distancePointPoint(aSketchPointCoords, aLineAStartPoint) - PT_PT_DIST) < 1.e-10)
+assert (math.fabs(model.distancePointPoint(aSketchPointCoords, aLineAStartPoint) - PT_PT_DIST) < 1.e-10)
assert (model.dof(aSketchFeature) == 5)
#=========================================================================
# Remove constraint, check the points are unconstrained now
aSession.startOperation()
aSketchPointCoords.setValue(0., 0.)
aSession.finishOperation()
-assert (math.fabs(distancePointPoint(aSketchPointCoords, aLineAStartPoint) - PT_PT_DIST) > 1.e-10)
+assert (math.fabs(model.distancePointPoint(aSketchPointCoords, aLineAStartPoint) - PT_PT_DIST) > 1.e-10)
assert (model.dof(aSketchFeature) == 6)
#=========================================================================
refattrA.setAttr(aLineAStartPoint)
refattrB.setAttr(aLineAEndPoint)
aSession.finishOperation()
-assert (math.fabs(distancePointPoint(aLineAStartPoint, aLineAEndPoint) - PT_LINE_DIST) < 1.e-10)
+assert (math.fabs(model.distancePointPoint(aLineAStartPoint, aLineAEndPoint) - PT_LINE_DIST) < 1.e-10)
assert (model.dof(aSketchFeature) == 5)
#=========================================================================
# End of test
norm = geomDataAPI_Dir(aSketchFeature.attribute("Norm"))
norm.setValue(0, 0, 1)
# add circle defined by 3 points
- circle = aSketchFeature.addFeature("SketchCircle")
- circle.string("CircleType").setValue("ThreePoints")
- geomDataAPI_Point2D(circle.attribute("FirstPoint")).setValue(-40., 50.)
- geomDataAPI_Point2D(circle.attribute("SecondPoint")).setValue(-50., 60.)
- geomDataAPI_Point2D(circle.attribute("ThirdPoint")).setValue(-60., 50.)
+ circle = aSketchFeature.addFeature("SketchMacroCircle")
+ circle.string("circle_type").setValue("circle_type_by_three_points")
+ geomDataAPI_Point2D(circle.attribute("first_point")).setValue(-40., 50.)
+ geomDataAPI_Point2D(circle.attribute("second_point")).setValue(-50., 60.)
+ geomDataAPI_Point2D(circle.attribute("third_point")).setValue(-60., 50.)
# add line
line = aSketchFeature.addFeature("SketchLine")
lineStart = geomDataAPI_Point2D(line.attribute("StartPoint"))
#=========================================================================
aSession.startOperation()
aSketchArc = aSketchFeature.addFeature("SketchArc")
-anArcCentr = geomDataAPI_Point2D(aSketchArc.attribute("ArcCenter"))
+anArcCentr = geomDataAPI_Point2D(aSketchArc.attribute("center_point"))
anArcCentr.setValue(10., 10.)
-anArcStartPoint = geomDataAPI_Point2D(aSketchArc.attribute("ArcStartPoint"))
+anArcStartPoint = geomDataAPI_Point2D(aSketchArc.attribute("start_point"))
anArcStartPoint.setValue(0., 50.)
-anArcEndPoint = geomDataAPI_Point2D(aSketchArc.attribute("ArcEndPoint"))
+anArcEndPoint = geomDataAPI_Point2D(aSketchArc.attribute("end_point"))
anArcEndPoint.setValue(50., 0.)
aSession.finishOperation()
assert (model.dof(aSketchFeature) == 5)
# Circle
aSession.startOperation()
aSketchCircle = aSketchFeature.addFeature("SketchCircle")
-anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("CircleCenter"))
-aCircleRadius = aSketchCircle.real("CircleRadius")
+anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("circle_center"))
+aCircleRadius = aSketchCircle.real("circle_radius")
anCircleCentr.setValue(-25., -25.)
aCircleRadius.setValue(25.)
aSession.finishOperation()
#=========================================================================
aSession.startOperation()
anExtCircle = aSketchFeature.addFeature("SketchCircle")
-anExtCircleCenter = geomDataAPI_Point2D(anExtCircle.attribute("CircleCenter"))
-anExtCircleRadius = anExtCircle.real("CircleRadius")
+anExtCircleCenter = geomDataAPI_Point2D(anExtCircle.attribute("circle_center"))
+anExtCircleRadius = anExtCircle.real("circle_radius")
anExtCircleCenter.setValue(-50., 50.)
anExtCircleRadius.setValue(10.)
anExtCircle.selection("External").selectSubShape("EDGE", "Sketch_1/Edge-SketchCircle_1_2")
anOrigShape = anOrigRes.shape()
assert (anOrigShape)
anOrigin = aSketchFeature.addFeature("SketchPoint")
-anOriginCoord = geomDataAPI_Point2D(anOrigin.attribute("PointCoordindates"))
+anOriginCoord = geomDataAPI_Point2D(anOrigin.attribute("PointCoordinates"))
anOriginCoord.setValue(0., 0.)
anOrigin.selection("External").setValue(anOrigRes, anOrigShape)
aSession.finishOperation()
+++ /dev/null
-"""
- TestConstraintMirror.py
- Unit test of SketchPlugin_ConstraintMirror class
-
- SketchPlugin_ConstraintMirror
- static const std::string MY_CONSTRAINT_MIRROR_ID("SketchConstraintMirror");
- data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::typeId());
- data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefListAttr::typeId());
- data()->addAttribute(SketchPlugin_Constraint::ENTITY_C(), ModelAPI_AttributeRefListAttr::typeId());
-
-"""
-from GeomDataAPI import *
-from ModelAPI import *
-import math
-from salome.shaper import model
-
-#=========================================================================
-# Initialization of the test
-#=========================================================================
-
-__updated__ = "2015-03-17"
-
-#=========================================================================
-# Auxiliary functions
-#=========================================================================
-def normalize(theDir):
- aLen = math.hypot(theDir[0], theDir[1])
- if aLen < 1.e-10:
- aLen = 1.0
- return [theDir[0] / aLen, theDir[1] / aLen]
-
-def checkMirror(theListInit, theListMirr, theMirrorLine):
- TOL = 6.e-5
- aListSize = theListInit.size()
-
- aLineStartPoint = geomDataAPI_Point2D(theMirrorLine.attribute("StartPoint"))
- aLineEndPoint = geomDataAPI_Point2D(theMirrorLine.attribute("EndPoint"))
- aLineDir = [aLineEndPoint.x() - aLineStartPoint.x(), aLineEndPoint.y() - aLineStartPoint.y()]
- aLineDir = normalize(aLineDir)
-
- for ind in range(0, aListSize):
- aFeatureB = ModelAPI_Feature.feature(theListInit.object(ind))
- aFeatureC = ModelAPI_Feature.feature(theListMirr.object(ind))
- assert(aFeatureB is not None)
- assert(aFeatureC is not None)
- assert(aFeatureB.getKind() == aFeatureC.getKind())
-
- anAttributes = []
- if (aFeatureB.getKind() == "SketchLine"):
- anAttributes = ['StartPoint', 'EndPoint']
- elif (aFeatureB.getKind() == "SketchArc"):
- anAttributes = ['ArcCenter', 'ArcStartPoint', 'ArcEndPoint']
-
- for key in anAttributes:
- aPointB = geomDataAPI_Point2D(aFeatureB.attribute(key))
- aPointC = geomDataAPI_Point2D(aFeatureC.attribute(key))
- aDir = [aPointC.x() - aPointB.x(), aPointC.y() - aPointB.y()]
- aDir = normalize(aDir)
- aDot = aLineDir[0] * aDir[0] + aLineDir[1] * aDir[1]
- assert math.fabs(aDot) < TOL, "aDot = {0}".format(aDot)
- aDir[0] = aLineEndPoint.x() - 0.5 * (aPointB.x() + aPointC.x())
- aDir[1] = aLineEndPoint.y() - 0.5 * (aPointB.y() + aPointC.y())
- aCross = aLineDir[0] * aDir[1] - aLineDir[1] * aDir[0]
- assert math.fabs(aCross) < TOL, "aCross = {0}".format(aCross)
-
-
-#=========================================================================
-# Start of test
-#=========================================================================
-aSession = ModelAPI_Session.get()
-aDocument = aSession.moduleDocument()
-#=========================================================================
-# Creation of a sketch
-#=========================================================================
-aSession.startOperation()
-aSketchCommonFeature = aDocument.addFeature("Sketch")
-aSketchFeature = featureToCompositeFeature(aSketchCommonFeature)
-origin = geomDataAPI_Point(aSketchFeature.attribute("Origin"))
-origin.setValue(0, 0, 0)
-dirx = geomDataAPI_Dir(aSketchFeature.attribute("DirX"))
-dirx.setValue(1, 0, 0)
-norm = geomDataAPI_Dir(aSketchFeature.attribute("Norm"))
-norm.setValue(0, 0, 1)
-aSession.finishOperation()
-#=========================================================================
-# Creation of an arc and two lines
-#=========================================================================
-# Arc
-aSession.startOperation()
-aSketchArc1 = aSketchFeature.addFeature("SketchArc")
-anArcCentr = geomDataAPI_Point2D(aSketchArc1.attribute("ArcCenter"))
-anArcCentr.setValue(10., 10.)
-anArcStartPoint = geomDataAPI_Point2D(aSketchArc1.attribute("ArcStartPoint"))
-anArcStartPoint.setValue(0., 50.)
-anArcEndPoint = geomDataAPI_Point2D(aSketchArc1.attribute("ArcEndPoint"))
-anArcEndPoint.setValue(50., 0.)
-aSession.finishOperation()
-# Line 1
-aSession.startOperation()
-aSketchLine1 = aSketchFeature.addFeature("SketchLine")
-aLine1StartPoint = geomDataAPI_Point2D(aSketchLine1.attribute("StartPoint"))
-aLine1EndPoint = geomDataAPI_Point2D(aSketchLine1.attribute("EndPoint"))
-aLine1StartPoint.setValue(0., 50.)
-aLine1EndPoint.setValue(0., 100.)
-aSession.finishOperation()
-# Line 2
-aSession.startOperation()
-aSketchLine2 = aSketchFeature.addFeature("SketchLine")
-aLine2StartPoint = geomDataAPI_Point2D(aSketchLine2.attribute("StartPoint"))
-aLine2EndPoint = geomDataAPI_Point2D(aSketchLine2.attribute("EndPoint"))
-aLine2StartPoint.setValue(50., 0.)
-aLine2EndPoint.setValue(100., 0.)
-aSession.finishOperation()
-assert (model.dof(aSketchFeature) == 13)
-#=========================================================================
-# Link arc points and lines points by the coincidence constraint
-#=========================================================================
-aSession.startOperation()
-aConstraint = aSketchFeature.addFeature("SketchConstraintCoincidence")
-reflistA = aConstraint.refattr("ConstraintEntityA")
-reflistB = aConstraint.refattr("ConstraintEntityB")
-reflistA.setAttr(anArcStartPoint)
-reflistB.setAttr(aLine1StartPoint)
-aConstraint.execute()
-aSession.finishOperation()
-aSession.startOperation()
-aConstraint = aSketchFeature.addFeature("SketchConstraintCoincidence")
-reflistA = aConstraint.refattr("ConstraintEntityA")
-reflistB = aConstraint.refattr("ConstraintEntityB")
-reflistA.setAttr(anArcEndPoint)
-reflistB.setAttr(aLine2StartPoint)
-aConstraint.execute()
-aSession.finishOperation()
-assert (model.dof(aSketchFeature) == 9)
-#=========================================================================
-# Add tangency constraint and check correctness
-#=========================================================================
-aSession.startOperation()
-aTangency = aSketchFeature.addFeature("SketchConstraintTangent")
-aRefObjectA = aTangency.refattr("ConstraintEntityA")
-aRefObjectB = aTangency.refattr("ConstraintEntityB")
-anObjectA = modelAPI_ResultConstruction(aSketchArc1.lastResult())
-anObjectB = modelAPI_ResultConstruction(aSketchLine1.lastResult())
-assert (anObjectA is not None)
-assert (anObjectB is not None)
-aRefObjectA.setObject(anObjectA)
-aRefObjectB.setObject(anObjectB)
-aTangency.execute()
-aSession.finishOperation()
-assert (model.dof(aSketchFeature) == 8)
-#=========================================================================
-# Create mirror line
-#=========================================================================
-aSession.startOperation()
-aMirrorLine = aSketchFeature.addFeature("SketchLine")
-aLineStartPoint = geomDataAPI_Point2D(aMirrorLine.attribute("StartPoint"))
-aLineEndPoint = geomDataAPI_Point2D(aMirrorLine.attribute("EndPoint"))
-aLineStartPoint.setValue(100., 0.)
-aLineEndPoint.setValue(100., 100.)
-aSession.finishOperation()
-assert (model.dof(aSketchFeature) == 12)
-#=========================================================================
-# Make mirror for objects created above
-#=========================================================================
-aSession.startOperation()
-aMirror = aSketchFeature.addFeature("SketchConstraintMirror")
-aRefObjectA = aMirror.refattr("ConstraintEntityA")
-aRefObjectA.setObject(modelAPI_ResultConstruction(aMirrorLine.firstResult()))
-aRefListInitial = aMirror.reflist("ConstraintMirrorList")
-aRefListInitial.append(aSketchLine1.lastResult())
-aRefListInitial.append(aSketchArc1.lastResult())
-aRefListInitial.append(aSketchLine2.lastResult())
-aMirror.execute()
-aSession.finishOperation()
-assert (model.dof(aSketchFeature) == 12)
-#=========================================================================
-# Verify the simmetricity of all mirrored objects
-#=========================================================================
-aRefListB = aMirror.reflist("ConstraintEntityB")
-aRefListC = aMirror.reflist("ConstraintEntityC")
-assert (aRefListB.size() == 3)
-assert (aRefListC.size() == 3)
-checkMirror(aRefListB, aRefListC, aMirrorLine)
-assert (model.dof(aSketchFeature) == 12)
-
-#=========================================================================
-# Remove object from mirror
-#=========================================================================
-aSession.startOperation()
-aRefListInitial.remove(aSketchLine2.lastResult())
-aSession.finishOperation()
-assert (aRefListB.size() == 2)
-assert (aRefListC.size() == 2)
-checkMirror(aRefListB, aRefListC, aMirrorLine)
-assert (model.dof(aSketchFeature) == 12)
-
-#=========================================================================
-# Clear list of mirrored features
-#=========================================================================
-aSession.startOperation()
-aRefListInitial.clear()
-assert (aRefListB.size() == 0)
-assert (aRefListC.size() == 0)
-# add arc once again
-aRefListInitial.append(aSketchArc1.lastResult())
-aSession.finishOperation()
-assert (aRefListB.size() == 1)
-assert (aRefListC.size() == 1)
-checkMirror(aRefListB, aRefListC, aMirrorLine)
-assert (model.dof(aSketchFeature) == 12)
-#=========================================================================
-# End of test
-#=========================================================================
-
-assert(model.checkPythonDump())
__updated__ = "2014-10-28"
-def distancePointPoint(pointA, pointB):
- """
- subroutine to calculate distance between two points
- result of calculated distance is has 10**-5 precision
- """
- xdiff = math.pow((pointA.x() - pointB.x()), 2)
- ydiff = math.pow((pointA.y() - pointB.y()), 2)
- return round(math.sqrt(xdiff + ydiff), 5)
-
aSession = ModelAPI_Session.get()
aDocument = aSession.moduleDocument()
#=========================================================================
aSession.startOperation()
aSketchArc = aSketchFeature.addFeature("SketchArc")
-anArcCentr = geomDataAPI_Point2D(aSketchArc.attribute("ArcCenter"))
+anArcCentr = geomDataAPI_Point2D(aSketchArc.attribute("center_point"))
anArcCentr.setValue(10., 10.)
-anArcStartPoint = geomDataAPI_Point2D(aSketchArc.attribute("ArcStartPoint"))
+anArcStartPoint = geomDataAPI_Point2D(aSketchArc.attribute("start_point"))
anArcStartPoint.setValue(0., 50.)
-anArcEndPoint = geomDataAPI_Point2D(aSketchArc.attribute("ArcEndPoint"))
+anArcEndPoint = geomDataAPI_Point2D(aSketchArc.attribute("end_point"))
anArcEndPoint.setValue(50., 0.)
aSession.finishOperation()
assert (model.dof(aSketchFeature) == 5)
# Circle
aSession.startOperation()
aSketchCircle = aSketchFeature.addFeature("SketchCircle")
-anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("CircleCenter"))
-aCircleRadius = aSketchCircle.real("CircleRadius")
+anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("circle_center"))
+aCircleRadius = aSketchCircle.real("circle_radius")
anCircleCentr.setValue(-25., -25)
aCircleRadius.setValue(25.)
aSession.finishOperation()
assert (model.dof(aSketchFeature) == 8)
-# Change the radius of the arc
-aSession.startOperation()
-RADIUS = 40
-anArcRadius = aSketchArc.real("ArcRadius")
-anArcRadius.setValue(RADIUS)
-aSession.finishOperation()
-assert (model.dof(aSketchFeature) == 8)
#=========================================================================
# Make a constraint to keep the radius of the arc
#=========================================================================
+RADIUS = 40
aSession.startOperation()
aConstraint = aSketchFeature.addFeature("SketchConstraintRadius")
aRadius = aConstraint.real("ConstraintValue")
aResult = aSketchArc.lastResult()
assert (aResult is not None)
aRefObject.setObject(modelAPI_ResultConstruction(aResult))
-aConstraint.execute()
+aRadius.setValue(RADIUS)
aSession.finishOperation()
assert (aRadius.isInitialized())
assert (aRefObject.isInitialized())
aResult = aSketchCircle.lastResult()
assert (aResult is not None)
aRefObject.setObject(modelAPI_ResultConstruction(aResult))
-aConstraint.execute()
+aRadius.setValue(RADIUS)
aSession.finishOperation()
assert (aRadius.isInitialized())
assert (aRefObject.isInitialized())
assert (model.dof(aSketchFeature) == 6)
#=========================================================================
# Perform some actions and checks:
-# 1. Check that constraints does not changes values
+# 1. Check that constraints does not change values
# 2. Move one point of the arc
# 3. Check that second point is moved also
#=========================================================================
-assert (math.fabs(distancePointPoint(anArcCentr, anArcStartPoint) - RADIUS) < 1.e-10)
-assert (math.fabs(distancePointPoint(anArcCentr, anArcEndPoint) - RADIUS) < 1.e-10)
+distCS = model.distancePointPoint(anArcCentr, anArcStartPoint)
+distCE = model.distancePointPoint(anArcCentr, anArcEndPoint)
+assert (math.fabs(distCS - RADIUS) < 1.e-10)
+assert (math.fabs(distCE - RADIUS) < 1.e-10)
anArcPrevEndPointX = anArcEndPoint.x()
anArcPrevEndPointY = anArcEndPoint.y()
# Move one point of the arc
aSession.finishOperation()
assert (anArcEndPoint.x() != anArcPrevEndPointX)
assert (anArcEndPoint.y() != anArcPrevEndPointY)
-assert (math.fabs(distancePointPoint(anArcCentr, anArcStartPoint) - RADIUS) < 1.e-10)
-assert (math.fabs(distancePointPoint(anArcCentr, anArcEndPoint) - RADIUS) < 1.e-10)
+distCS = model.distancePointPoint(anArcCentr, anArcStartPoint)
+distCE = model.distancePointPoint(anArcCentr, anArcEndPoint)
+assert (math.fabs(distCS - RADIUS) < 1.e-10)
+assert (math.fabs(distCE - RADIUS) < 1.e-10)
assert (model.dof(aSketchFeature) == 6)
#=========================================================================
# 4. Move the centr or the point of the arc
#=========================================================================
assert (anCircleCentr.x() == -25)
assert (anCircleCentr.y() == -25)
-assert (aCircleRadius.value() == 25)
+assert (aCircleRadius.value() == RADIUS)
aSession.startOperation()
anCircleCentr.setValue(100., 100.)
aSession.finishOperation()
assert (anCircleCentr.x() == 100)
assert (anCircleCentr.y() == 100)
-assert (aCircleRadius.value() == 25)
+assert (aCircleRadius.value() == RADIUS)
assert (model.dof(aSketchFeature) == 6)
#=========================================================================
# End of test
__updated__ = "2015-03-17"
-def distancePointPoint(thePoint1, thePoint2):
- """
- subroutine to calculate distance between two points
- result of calculated distance is has 10**-5 precision
- """
- aDist = math.sqrt((thePoint1.x()-thePoint2.x())**2 + (thePoint1.y()-thePoint2.y())**2)
- return round(aDist, 5)
-
def distancePointLine(point, line):
"""
subroutine to calculate distance between point and line
subroutine to check that the line is tangent to arc/circle
"""
if (theArc.getKind() == "SketchCircle"):
- aCenter = geomDataAPI_Point2D(theArc.attribute("CircleCenter"))
- aRadius = theArc.real("CircleRadius").value()
+ aCenter = geomDataAPI_Point2D(theArc.attribute("circle_center"))
+ aRadius = theArc.real("circle_radius").value()
else:
- aCenter = geomDataAPI_Point2D(theArc.attribute("ArcCenter"))
- aStartPnt = geomDataAPI_Point2D(theArc.attribute("ArcStartPoint"))
- aRadius = distancePointPoint(aStartPnt, aCenter)
+ aCenter = geomDataAPI_Point2D(theArc.attribute("center_point"))
+ aStartPnt = geomDataAPI_Point2D(theArc.attribute("start_point"))
+ aRadius = model.distancePointPoint(aStartPnt, aCenter)
aDist = distancePointLine(aCenter, theLine)
assert math.fabs(aDist - aRadius) < 2.e-5, "aDist = {0}, aRadius = {1}".format(aDist, aRadius)
aRadii = []
for anArc in anArcs:
if (anArc.getKind() == "SketchCircle"):
- aCenter = geomDataAPI_Point2D(anArc.attribute("CircleCenter"))
- aRadius = anArc.real("CircleRadius").value()
+ aCenter = geomDataAPI_Point2D(anArc.attribute("circle_center"))
+ aRadius = anArc.real("circle_radius").value()
else:
- aCenter = geomDataAPI_Point2D(anArc.attribute("ArcCenter"))
- aStartPnt = geomDataAPI_Point2D(anArc.attribute("ArcStartPoint"))
- aRadius = distancePointPoint(aStartPnt, aCenter)
+ aCenter = geomDataAPI_Point2D(anArc.attribute("center_point"))
+ aStartPnt = geomDataAPI_Point2D(anArc.attribute("start_point"))
+ aRadius = model.distancePointPoint(aStartPnt, aCenter)
aCenters.append(aCenter)
aRadii.append(aRadius)
- aDist = distancePointPoint(aCenters[0], aCenters[1])
+ aDist = model.distancePointPoint(aCenters[0], aCenters[1])
aRSum = aRadii[0] + aRadii[1]
aRDiff = math.fabs(aRadii[0] - aRadii[1])
assert math.fabs(aDist - aRSum) < 2.e-5 or math.fabs(aDist - aRDiff) < 2.e-5, "aDist = {0}, aRSum = {1}, aRDiff = {2}".format(aDist, aRSum, aRDiff)
# Arc
aSession.startOperation()
aSketchArc1 = aSketchFeature.addFeature("SketchArc")
-anArcCentr = geomDataAPI_Point2D(aSketchArc1.attribute("ArcCenter"))
+anArcCentr = geomDataAPI_Point2D(aSketchArc1.attribute("center_point"))
anArcCentr.setValue(10., 10.)
-anArcStartPoint = geomDataAPI_Point2D(aSketchArc1.attribute("ArcStartPoint"))
+anArcStartPoint = geomDataAPI_Point2D(aSketchArc1.attribute("start_point"))
anArcStartPoint.setValue(0., 50.)
-anArcEndPoint = geomDataAPI_Point2D(aSketchArc1.attribute("ArcEndPoint"))
+anArcEndPoint = geomDataAPI_Point2D(aSketchArc1.attribute("end_point"))
anArcEndPoint.setValue(50., 0.)
aSession.finishOperation()
# Line 1
# Arc 1
aSession.startOperation()
aSketchArc1 = aSketchFeature.addFeature("SketchArc")
-anArc1Centr = geomDataAPI_Point2D(aSketchArc1.attribute("ArcCenter"))
+anArc1Centr = geomDataAPI_Point2D(aSketchArc1.attribute("center_point"))
anArc1Centr.setValue(10., 10.)
-anArc1StartPoint = geomDataAPI_Point2D(aSketchArc1.attribute("ArcStartPoint"))
+anArc1StartPoint = geomDataAPI_Point2D(aSketchArc1.attribute("start_point"))
anArc1StartPoint.setValue(50., 0.)
-anArc1EndPoint = geomDataAPI_Point2D(aSketchArc1.attribute("ArcEndPoint"))
+anArc1EndPoint = geomDataAPI_Point2D(aSketchArc1.attribute("end_point"))
anArc1EndPoint.setValue(0., 50.)
aSession.finishOperation()
# Arc 2
aSession.startOperation()
-aSketchArc2 = aSketchFeature.addFeature("SketchArc")
-aSketchArc2.string("ArcType").setValue("ThreePoints")
-anArc2Centr = geomDataAPI_Point2D(aSketchArc2.attribute("ArcCenter"))
-anArc2StartPoint = geomDataAPI_Point2D(aSketchArc2.attribute("ArcStartPoint"))
+aSketchArc2 = aSketchFeature.addFeature("SketchMacroArc")
+aSketchArc2.string("arc_type").setValue("by_three_points")
+anArc2StartPoint = geomDataAPI_Point2D(aSketchArc2.attribute("start_point_2"))
anArc2StartPoint.setValue(0., 50.)
-anArc2EndPoint = geomDataAPI_Point2D(aSketchArc2.attribute("ArcEndPoint"))
+anArc2EndPoint = geomDataAPI_Point2D(aSketchArc2.attribute("end_point_2"))
anArc2EndPoint.setValue(-50., 0.)
-anArc2PassedPoint = geomDataAPI_Point2D(aSketchArc2.attribute("ArcPassedPoint"))
+anArc2PassedPoint = geomDataAPI_Point2D(aSketchArc2.attribute("passed_point"))
anArc2PassedPoint.setValue(-40., 40.)
aSession.finishOperation()
-assert (model.dof(aSketchFeature) == 17)
+#assert (model.dof(aSketchFeature) == 17)
+aSketchArc2 = model.lastSubFeature(aSketchFeature, "SketchArc")
+anArc2Centr = geomDataAPI_Point2D(aSketchArc2.attribute("center_point"))
+anArc2StartPoint = geomDataAPI_Point2D(aSketchArc2.attribute("start_point"))
#=========================================================================
# Link points of arcs by the coincidence constraint
#=========================================================================
# 3.2 tangency between non-connected arcs
aSession.startOperation()
aSketchArc3 = aSketchFeature.addFeature("SketchArc")
-anArc3Centr = geomDataAPI_Point2D(aSketchArc3.attribute("ArcCenter"))
+anArc3Centr = geomDataAPI_Point2D(aSketchArc3.attribute("center_point"))
anArc3Centr.setValue(100., -10.)
-anArc3StartPoint = geomDataAPI_Point2D(aSketchArc3.attribute("ArcStartPoint"))
+anArc3StartPoint = geomDataAPI_Point2D(aSketchArc3.attribute("start_point"))
anArc3StartPoint.setValue(70., -10.)
-anArc3EndPoint = geomDataAPI_Point2D(aSketchArc3.attribute("ArcEndPoint"))
+anArc3EndPoint = geomDataAPI_Point2D(aSketchArc3.attribute("end_point"))
anArc3EndPoint.setValue(100., 20.)
aSession.finishOperation()
assert (model.dof(aSketchFeature) == 19)
# 3.3 tangency between arc and circle
aSession.startOperation()
aCircle1 = aSketchFeature.addFeature("SketchCircle")
-aCircleCenter = geomDataAPI_Point2D(aCircle1.attribute("CircleCenter"))
-aCircleRadius = aCircle1.real("CircleRadius")
+aCircleCenter = geomDataAPI_Point2D(aCircle1.attribute("circle_center"))
+aCircleRadius = aCircle1.real("circle_radius")
aCircleCenter.setValue(150., 100.)
aCircleRadius.setValue(50.)
aSession.finishOperation()
# 3.4 tangency between two circles
aSession.startOperation()
aCircle2 = aSketchFeature.addFeature("SketchCircle")
-aCircleCenter = geomDataAPI_Point2D(aCircle2.attribute("CircleCenter"))
-aCircleRadius = aCircle2.real("CircleRadius")
+aCircleCenter = geomDataAPI_Point2D(aCircle2.attribute("circle_center"))
+aCircleRadius = aCircle2.real("circle_radius")
aCircleCenter.setValue(120., 70.)
aCircleRadius.setValue(20.)
aSession.finishOperation()
# TEST 4. Creating of tangency arc by the option of the SketchArc feature
#=========================================================================
aSession.startOperation()
-aSketchArc3 = aSketchFeature.addFeature("SketchArc")
-aSketchArc3.string("ArcType").setValue("Tangent")
-anArc3Start = aSketchArc3.refattr("ArcTangentPoint")
+aSketchArc3 = aSketchFeature.addFeature("SketchMacroArc")
+aSketchArc3.string("arc_type").setValue("by_tangent_edge")
+anArc3Start = aSketchArc3.refattr("tangent_point")
anArc3Start.setAttr(anArc1StartPoint)
-anArc3EndPoint = geomDataAPI_Point2D(aSketchArc3.attribute("ArcEndPoint"))
+anArc3EndPoint = geomDataAPI_Point2D(aSketchArc3.attribute("end_point_3"))
anArc3EndPoint.setValue(anArc1StartPoint.x()-5, anArc1StartPoint.y()-30)
aSession.finishOperation()
+aSketchArc3 = model.lastSubFeature(aSketchFeature, "SketchArc")
checkArcArcTangency(aSketchArc1, aSketchArc3)
# freeze radius of tangent arc
aSession.startOperation()
aLineStart.setValue(100., 100.)
aLineEnd.setValue(200., 200.)
aCircle = aSketchFeature.addFeature("SketchCircle")
-aCircleCenter = geomDataAPI_Point2D(aCircle.attribute("CircleCenter"))
-aCircleRadius = aCircle.real("CircleRadius")
+aCircleCenter = geomDataAPI_Point2D(aCircle.attribute("circle_center"))
+aCircleRadius = aCircle.real("circle_radius")
aCircleCenter.setValue(150., 100.)
aCircleRadius.setValue(20.)
aSession.finishOperation()
--- /dev/null
+"""
+ TestCreateArc.py
+
+ static const std::string MY_SKETCH_ARC_ID("SketchArc");
+ static const std::string MY_CENTER_ID = "center_point";
+ static const std::string MY_START_ID = "start_point";
+ static const std::string MY_END_ID = "end_point";
+ data()->addAttribute(SketchPlugin_Arc::CENTER_ID(), GeomDataAPI_Point2D::typeId());
+ data()->addAttribute(SketchPlugin_Arc::START_ID(), GeomDataAPI_Point2D::typeId());
+ data()->addAttribute(SketchPlugin_Arc::END_ID(), GeomDataAPI_Point2D::typeId());
+"""
+
+#=========================================================================
+# Initialization of the test
+#=========================================================================
+from GeomDataAPI import *
+from ModelAPI import *
+import math
+from salome.shaper import model
+
+__updated__ = "2017-03-28"
+
+TOLERANCE = 1.e-7
+
+#=========================================================================
+# Auxiliary functions
+#=========================================================================
+
+def verifyLastArc(theSketch, theCenter, theStart, theEnd):
+ """
+ subroutine to verify position of last arc in the sketch
+ """
+ aLastArc = model.lastSubFeature(theSketch, "SketchArc")
+ aCenterPnt = geomDataAPI_Point2D(aLastArc.attribute("center_point"))
+ aStartPnt = geomDataAPI_Point2D(aLastArc.attribute("start_point"))
+ aEndPnt = geomDataAPI_Point2D(aLastArc.attribute("end_point"))
+ if len(theCenter):
+ verifyPointCoordinates(aCenterPnt, theCenter[0], theCenter[1])
+ if len(theStart):
+ verifyPointCoordinates(aStartPnt, theStart[0], theStart[1])
+ if len(theEnd):
+ verifyPointCoordinates(aEndPnt, theEnd[0], theEnd[1])
+ model.assertSketchArc(aLastArc)
+
+def verifyPointCoordinates(thePoint, theX, theY):
+ assert thePoint.x() == theX and thePoint.y() == theY, "Wrong '{0}' point ({1}, {2}), expected ({3}, {4})".format(thePoint.id(), thePoint.x(), thePoint.y(), theX, theY)
+
+
+aSession = ModelAPI_Session.get()
+aDocument = aSession.moduleDocument()
+#=========================================================================
+# Creation of a sketch
+#=========================================================================
+aSession.startOperation()
+aSketchCommonFeature = aDocument.addFeature("Sketch")
+aSketchFeature = featureToCompositeFeature(aSketchCommonFeature)
+origin = geomDataAPI_Point(aSketchFeature.attribute("Origin"))
+origin.setValue(0, 0, 0)
+dirx = geomDataAPI_Dir(aSketchFeature.attribute("DirX"))
+dirx.setValue(1, 0, 0)
+norm = geomDataAPI_Dir(aSketchFeature.attribute("Norm"))
+norm.setValue(0, 0, 1)
+aSession.finishOperation()
+
+#=========================================================================
+# Test 1. Create an arc by center, start and end points
+#=========================================================================
+aCenter = [10., 10.]
+aStart = [0., 50.]
+aEnd = [50., 0.]
+aSession.startOperation()
+aSketchArc = aSketchFeature.addFeature("SketchArc")
+assert (aSketchArc.getKind() == "SketchArc")
+anArcCenter = geomDataAPI_Point2D(aSketchArc.attribute("center_point"))
+assert (not anArcCenter.isInitialized())
+anArcCenter.setValue(aCenter[0], aCenter[1])
+anArcStartPoint = geomDataAPI_Point2D(aSketchArc.attribute("start_point"))
+assert (not anArcStartPoint.isInitialized())
+anArcStartPoint.setValue(aStart[0], aStart[1])
+anArcEndPoint = geomDataAPI_Point2D(aSketchArc.attribute("end_point"))
+assert (not anArcEndPoint.isInitialized())
+anArcEndPoint.setValue(aEnd[0], aEnd[1])
+aSession.finishOperation()
+verifyLastArc(aSketchFeature, aCenter, aStart, aEnd)
+# Move center
+aCenter = [15., 20.]
+aSession.startOperation()
+anArcCenter.setValue(aCenter[0], aCenter[1])
+aSession.finishOperation()
+verifyLastArc(aSketchFeature, [], [], [])
+# Move start point
+deltaX, deltaY = 5., 2.
+aStart = [anArcStartPoint.x() + deltaX, anArcStartPoint.y() + deltaY]
+aSession.startOperation()
+anArcStartPoint.setValue(aStart[0], aStart[1])
+aSession.finishOperation()
+verifyLastArc(aSketchFeature, [], [], [])
+# Move end point
+aEnd = [anArcEndPoint.x() - deltaX, anArcEndPoint.y() - deltaY]
+aSession.startOperation()
+anArcEndPoint.setValue(aEnd[0], aEnd[1])
+aSession.finishOperation()
+verifyLastArc(aSketchFeature, [], [], [])
+# Check that changing the radius does not affect arc
+aSession.startOperation()
+anArcRadius = aSketchArc.real("radius")
+aPrevRadius = anArcRadius.value();
+anArcRadius.setValue(aPrevRadius + 10.)
+aSession.finishOperation()
+assert (math.fabs(anArcRadius.value() - aPrevRadius) < TOLERANCE)
+verifyLastArc(aSketchFeature, [], [], [])
+# Check that changing the angle does not affect arc
+aSession.startOperation()
+anArcAngle = aSketchArc.real("angle")
+aPrevAngle = anArcAngle.value()
+anArcAngle.setValue(aPrevAngle + 10.)
+aSession.finishOperation()
+assert (math.fabs(anArcAngle.value() - aPrevAngle) < TOLERANCE)
+verifyLastArc(aSketchFeature, [], [], [])
+
+#=========================================================================
+# End of test
+#=========================================================================
+
+assert(model.checkPythonDump())
#=========================================================================
TOLERANCE = 1.e-7
-def getLastCircle(theSketch):
- """
- obtains last feature from the sketch and generates error if the feature is not a circle
- """
- expectedKind = "SketchCircle"
- for anIndex in range(theSketch.numberOfSubs() - 1, -1, -1):
- aSub = theSketch.subFeature(anIndex)
- if (aSub.getKind() == expectedKind):
- return aSub
-
def verifyLastCircle(theSketch, theX, theY, theR):
"""
subroutine to verify position of last circle in the sketch
"""
- aLastCircle = getLastCircle(theSketch)
+ aLastCircle = model.lastSubFeature(theSketch, "SketchCircle")
aCenter = geomDataAPI_Point2D(aLastCircle.attribute("circle_center"))
verifyPointCoordinates(aCenter, theX, theY)
aRadius = aLastCircle.real("circle_radius")
assert aRadius.value() == theR, "Wrong radius {0}, expected {1}".format(aRadius.value(), theR)
def verifyPointCoordinates(thePoint, theX, theY):
- assert thePoint.x() == theX and thePoint.y() == theY, "Wrong '{0}' point ({1}, {2}), expected ({3}, {4})".format(thePoint.attributeType(), thePoint.x(), thePoint.y(), theX, theY)
+ assert thePoint.x() == theX and thePoint.y() == theY, "Wrong '{0}' point ({1}, {2}), expected ({3}, {4})".format(thePoint.id(), thePoint.x(), thePoint.y(), theX, theY)
def verifyPointOnLine(thePoint, theLine):
aDistance = distancePointLine(thePoint, theLine)
def verifyTangentCircles(theCircle1, theCircle2):
aCenter1 = geomDataAPI_Point2D(theCircle1.attribute("circle_center"))
aCenter2 = geomDataAPI_Point2D(theCircle2.attribute("circle_center"))
- aDistCC = distancePointPoint(aCenter1, aCenter2)
+ aDistCC = model.distancePointPoint(aCenter1, aCenter2)
aRadius1 = theCircle1.real("circle_radius").value()
aRadius2 = theCircle2.real("circle_radius").value()
aRSum = aRadius1 + aRadius2
aRDiff = math.fabs(aRadius1 - aRadius2)
assert math.fabs(aRSum - aDistCC) < TOLERANCE or math.fabs(aRDiff - aDistCC) < TOLERANCE, "Circles do not tangent"
-def distancePointPoint(thePoint1, thePoint2):
- return thePoint1.pnt().distance(thePoint2.pnt())
-
def distancePointLine(thePoint, theLine):
aLineStart = geomDataAPI_Point2D(theLine.attribute("StartPoint")).pnt().xy()
aLineEnd = geomDataAPI_Point2D(theLine.attribute("EndPoint")).pnt().xy()
aCircleType.setValue("circle_type_by_center_and_passed_points")
aCircleCenter.setValue(-25., -25)
aCirclePassed.setValue(0., -25.)
-aRadius = distancePointPoint(aCircleCenter, aCirclePassed)
+aRadius = model.distancePointPoint(aCircleCenter, aCirclePassed)
aSession.finishOperation()
assert (aSketchFeature.numberOfSubs() == 2)
verifyLastCircle(aSketchFeature, -25., -25., aRadius)
# Test 3. Create a circle as a macro-feature by center and passed point coincident to other points
#=========================================================================
# get previous circle
-aPrevCircle = getLastCircle(aSketchFeature)
+aPrevCircle = model.lastSubFeature(aSketchFeature, "SketchCircle")
aPrevCenter = geomDataAPI_Point2D(aPrevCircle.attribute("circle_center"))
# create additional point
aPointCoodinates = [0., 0.]
aSession.startOperation()
aPoint = aSketchFeature.addFeature("SketchPoint")
-aPointCoord = geomDataAPI_Point2D(aPoint.attribute("PointCoordindates"))
+aPointCoord = geomDataAPI_Point2D(aPoint.attribute("PointCoordinates"))
aPointCoord.setValue(aPointCoodinates[0], aPointCoodinates[1])
aSession.finishOperation()
# create new circle
aCenter.setValue(aPointCoord.pnt())
aPassedRef.setAttr(aPrevCenter)
aPassed.setValue(aPrevCenter.pnt())
-aRadius = distancePointPoint(aPrevCenter, aPointCoord)
+aRadius = model.distancePointPoint(aPrevCenter, aPointCoord)
aSession.finishOperation()
assert (aSketchFeature.numberOfSubs() == 6)
verifyPointCoordinates(aPointCoord, aPointCoodinates[0], aPointCoodinates[1])
# Test 4. Create a circle as a macro-feature by center on a line and passed point on another circle
#=========================================================================
# get previous circle
-aPrevCircle = getLastCircle(aSketchFeature)
+aPrevCircle = model.lastSubFeature(aSketchFeature, "SketchCircle")
aPrevCenter = geomDataAPI_Point2D(aPrevCircle.attribute("circle_center"))
aPrevCenterXY = [aPrevCenter.x(), aPrevCenter.y()]
aPrevRadius = aPrevCircle.real("circle_radius").value()
aCenter.setValue(anExpectedCenter[0], anExpectedCenter[1])
aPassedRef.setObject(aPrevCircle.lastResult())
aPassed.setValue(aPrevCenter.x() + aPrevRadius, aPrevCenter.y())
-aRadius = distancePointPoint(aCenter, aPassed)
+aRadius = model.distancePointPoint(aCenter, aPassed)
aSession.finishOperation()
assert (aSketchFeature.numberOfSubs() == 10)
# check connected features do not change their positions
verifyPointCoordinates(aStartPnt, aLineStart[0], aLineStart[1])
verifyPointCoordinates(aEndPnt, aLineEnd[0], aLineEnd[1])
# verify newly created circle
-aCircle = getLastCircle(aSketchFeature)
+aCircle = model.lastSubFeature(aSketchFeature, "SketchCircle")
aCenter = geomDataAPI_Point2D(aCircle.attribute("circle_center"))
verifyPointCoordinates(aCenter, anExpectedCenter[0], anExpectedCenter[1])
verifyPointOnLine(aCenter, aLine)
aSession.finishOperation()
aLastFeature = aSketchFeature.subFeature(aSketchFeature.numberOfSubs() - 1)
assert aLastFeature.getKind() == "SketchMacroCircle", "ERROR: SketchMacroCircle has NOT expected to be valid"
+aSession.startOperation()
aDocument.removeFeature(aCircle)
+aSession.finishOperation()
assert (aSketchFeature.numberOfSubs() == 10)
#=========================================================================
#=========================================================================
TOLERANCE = 1.e-7
-def getLastCircle(theSketch):
- """
- obtains last feature from the sketch and generates error if the feature is not a circle
- """
- expectedKind = "SketchCircle"
- for anIndex in range(theSketch.numberOfSubs() - 1, -1, -1):
- aSub = theSketch.subFeature(anIndex)
- if (aSub.getKind() == expectedKind):
- return aSub
-
def verifyLastCircle(theSketch, theX, theY, theR):
"""
subroutine to verify position of last circle in the sketch
"""
- aLastCircle = getLastCircle(theSketch)
+ aLastCircle = model.lastSubFeature(theSketch, "SketchCircle")
aCenter = geomDataAPI_Point2D(aLastCircle.attribute("circle_center"))
verifyPointCoordinates(aCenter, theX, theY)
aRadius = aLastCircle.real("circle_radius")
def verifyPointOnCircle(thePoint, theCircle):
aCircleCenter = geomDataAPI_Point2D(theCircle.attribute("circle_center"))
- aDistCP = distancePointPoint(aCircleCenter, thePoint)
+ aDistCP = model.distancePointPoint(aCircleCenter, thePoint)
aCircleRadius = theCircle.real("circle_radius").value()
assert math.fabs(aDistCP - aCircleRadius) < TOLERANCE, "Point is not on circle, distance: {0}, radius of circle: {1}".format(aDistCP, aCircleRadius)
def verifyTangentCircles(theCircle1, theCircle2):
aCenter1 = geomDataAPI_Point2D(theCircle1.attribute("circle_center"))
aCenter2 = geomDataAPI_Point2D(theCircle2.attribute("circle_center"))
- aDistCC = distancePointPoint(aCenter1, aCenter2)
+ aDistCC = model.distancePointPoint(aCenter1, aCenter2)
aRadius1 = theCircle1.real("circle_radius").value()
aRadius2 = theCircle2.real("circle_radius").value()
verifyTangentCircular(aDistCC, aRadius1, aRadius2)
aCircleCenter = geomDataAPI_Point2D(theCircle.attribute("circle_center"))
anArcCenter = geomDataAPI_Point2D(theArc.attribute("center_point"))
anArcStart = geomDataAPI_Point2D(theArc.attribute("start_point"))
- aDistCC = distancePointPoint(aCircleCenter, anArcCenter)
+ aDistCC = model.distancePointPoint(aCircleCenter, anArcCenter)
aCircleRadius = theCircle.real("circle_radius").value()
- anArcRadius = distancePointPoint(anArcCenter, anArcStart)
+ anArcRadius = model.distancePointPoint(anArcCenter, anArcStart)
verifyTangentCircular(aDistCC, aCircleRadius, anArcRadius)
def verifyTangentCircular(theDistBetweenCenters, theRadius1, theRadius2):
aDistCL = distancePointLine(aCenter, theLine)
assert math.fabs(aDistCL - aRadius) < TOLERANCE, "Circle and line are not tangent"
-def distancePointPoint(thePoint1, thePoint2):
- return thePoint1.pnt().distance(thePoint2.pnt())
-
def distancePointLine(thePoint, theLine):
aLineStart = geomDataAPI_Point2D(theLine.attribute("StartPoint")).pnt().xy()
aLineEnd = geomDataAPI_Point2D(theLine.attribute("EndPoint")).pnt().xy()
# Test 2. Create a circle by three points coincident to other points
#=========================================================================
# get previous circle
-aPrevCircle = getLastCircle(aSketchFeature)
+aPrevCircle = model.lastSubFeature(aSketchFeature, "SketchCircle")
aPrevCenter = geomDataAPI_Point2D(aPrevCircle.attribute("circle_center"))
aPrevCenterXY = [aPrevCenter.x(), aPrevCenter.y()]
aPrevCircleRadius = aPrevCircle.real("circle_radius").value()
aLineEnd = [10., 50.]
aSession.startOperation()
aPoint = aSketchFeature.addFeature("SketchPoint")
-aPointCoord = geomDataAPI_Point2D(aPoint.attribute("PointCoordindates"))
+aPointCoord = geomDataAPI_Point2D(aPoint.attribute("PointCoordinates"))
aPointCoord.setValue(aPointCoodinates[0], aPointCoodinates[1])
aLine = aSketchFeature.addFeature("SketchLine")
aStartPnt = geomDataAPI_Point2D(aLine.attribute("StartPoint"))
verifyPointCoordinates(aPointCoord, aPointCoodinates[0], aPointCoodinates[1])
verifyPointCoordinates(aStartPnt, aLineStart[0], aLineStart[1])
# check newly created circle passes through the points
-aCircle = getLastCircle(aSketchFeature)
+aCircle = model.lastSubFeature(aSketchFeature, "SketchCircle")
verifyPointOnCircle(aPrevCenter, aCircle)
verifyPointOnCircle(aPointCoord, aCircle)
verifyPointOnCircle(aStartPnt, aCircle)
verifyPointCoordinates(anArcStartPnt, anArcStart[0], anArcStart[1])
verifyPointCoordinates(anArcEndPnt, anArcEnd[0], anArcEnd[1])
# check newly created circle passes through the points
-aCircle = getLastCircle(aSketchFeature)
+aCircle = model.lastSubFeature(aSketchFeature, "SketchCircle")
verifyTangentCircles(aCircle, aPrevCircle)
verifyTangentCircleArc(aCircle, anArc)
verifyTangentCircleLine(aCircle, aLine)
assert (not aSecondPointRef.isInitialized())
assert (not aThirdPointRef.isInitialized())
-def getLastCircle(theSketch):
- """
- obtains last feature from the sketch and generates error if the feature is not a circle
- """
- expectedKind = "SketchCircle"
- for anIndex in range(theSketch.numberOfSubs() - 1, -1, -1):
- aSub = theSketch.subFeature(anIndex)
- if (aSub.getKind() == expectedKind):
- return aSub
-
def verifyLastCircle(theSketch, theX, theY, theR):
"""
subroutine to verify position of last circle in the sketch
"""
- aLastCircle = getLastCircle(theSketch)
+ aLastCircle = model.lastSubFeature(theSketch, "SketchCircle")
aCenter = geomDataAPI_Point2D(aLastCircle.attribute("circle_center"))
verifyPointCoordinates(aCenter, theX, theY)
aRadius = aLastCircle.real("circle_radius")
def verifyPointCoordinates(thePoint, theX, theY):
assert thePoint.x() == theX and thePoint.y() == theY, "Wrong '{0}' point ({1}, {2}), expected ({3}, {4})".format(thePoint.attributeType(), thePoint.x(), thePoint.y(), theX, theY)
-def distancePointPoint(thePoint1, thePoint2):
- return thePoint1.pnt().distance(thePoint2.pnt())
-
#=========================================================================
# Start of test
aPassedPoint.setValue(aLineEnd.pnt())
aSession.finishOperation()
-aRadius = distancePointPoint(aLineStart, aLineEnd)
+aRadius = model.distancePointPoint(aLineStart, aLineEnd)
NB_FEATURES_EXPECTED = 4 # line, circle and two coincidences
assert (aSketchFeature.numberOfSubs() == NB_FEATURES_EXPECTED), "Number of features in sketch {}, expected {}".format(aSketchFeature.numberOfSubs(), NB_FEATURES_EXPECTED)
verifyLastCircle(aSketchFeature, aLineStart.x(), aLineStart.y(), aRadius)
allFeatures.append(aSketchLine)
# Arc
aSketchArc = theSketch.addFeature("SketchArc")
- aStartPoint2 = geomDataAPI_Point2D(aSketchArc.attribute("ArcStartPoint"))
- aEndPoint2 = geomDataAPI_Point2D(aSketchArc.attribute("ArcEndPoint"))
- aCenterPoint = geomDataAPI_Point2D(aSketchArc.attribute("ArcCenter"))
+ aStartPoint2 = geomDataAPI_Point2D(aSketchArc.attribute("start_point"))
+ aEndPoint2 = geomDataAPI_Point2D(aSketchArc.attribute("end_point"))
+ aCenterPoint = geomDataAPI_Point2D(aSketchArc.attribute("center_point"))
aCenterPoint.setValue(20., 10.)
aStartPoint2.setValue(10., 10.)
aEndPoint2.setValue(20., 0.)
checkArcLineSmoothness(aConnectedFeatures[1], aConnectedFeatures[0])
def checkArcLineSmoothness(theArc, theLine):
- aCenter = geomDataAPI_Point2D(theArc.attribute("ArcCenter"))
+ aCenter = geomDataAPI_Point2D(theArc.attribute("center_point"))
aDistance = distancePointLine(aCenter, theLine)
aRadius = arcRadius(theArc)
assert(math.fabs(aRadius - aDistance) < TOLERANCE)
def checkArcArcSmoothness(theArc1, theArc2):
- aCenter1 = geomDataAPI_Point2D(theArc1.attribute("ArcCenter"))
- aCenter2 = geomDataAPI_Point2D(theArc2.attribute("ArcCenter"))
- aDistance = distancePointPoint(aCenter1, aCenter2)
+ aCenter1 = geomDataAPI_Point2D(theArc1.attribute("center_point"))
+ aCenter2 = geomDataAPI_Point2D(theArc2.attribute("center_point"))
+ aDistance = model.distancePointPoint(aCenter1, aCenter2)
aRadius1 = arcRadius(theArc1)
aRadius2 = arcRadius(theArc2)
aRadSum = aRadius1 + aRadius2
return [aFeatureA, aFeatureB]
def arcRadius(theArc):
- aCenter = geomDataAPI_Point2D(theArc.attribute("ArcCenter"))
- aStart = geomDataAPI_Point2D(theArc.attribute("ArcStartPoint"))
- return distancePointPoint(aCenter, aStart)
-
-def distancePointPoint(thePoint1, thePoint2):
- return math.hypot(thePoint1.x() - thePoint2.x(), thePoint1.y() - thePoint2.y())
+ aCenter = geomDataAPI_Point2D(theArc.attribute("center_point"))
+ aStart = geomDataAPI_Point2D(theArc.attribute("start_point"))
+ return model.distancePointPoint(aCenter, aStart)
def distancePointLine(thePoint, theLine):
aLineStart = geomDataAPI_Point2D(theLine.attribute("StartPoint"))
aLineEnd = geomDataAPI_Point2D(theLine.attribute("EndPoint"))
- aLength = distancePointPoint(aLineStart, aLineEnd)
+ aLength = model.distancePointPoint(aLineStart, aLineEnd)
aDir1x, aDir1y = aLineEnd.x() - aLineStart.x(), aLineEnd.y() - aLineStart.y()
aDir2x, aDir2y = thePoint.x() - aLineStart.x(), thePoint.y() - aLineStart.y()
__updated__ = "2017-03-06"
def isArcLineSmooth(theArc, theLine, theTolerance):
- aCenter = geomDataAPI_Point2D(theArc.attribute("ArcCenter"))
+ aCenter = geomDataAPI_Point2D(theArc.attribute("center_point"))
aDistance = distancePointLine(aCenter, theLine)
aRadius = arcRadius(theArc)
return math.fabs(aRadius - aDistance) < theTolerance
def isArcArcSmooth(theArc1, theArc2, theTolerance):
- aCenter1 = geomDataAPI_Point2D(theArc1.attribute("ArcCenter"))
- aCenter2 = geomDataAPI_Point2D(theArc2.attribute("ArcCenter"))
- aDistance = distancePointPoint(aCenter1, aCenter2)
+ aCenter1 = geomDataAPI_Point2D(theArc1.attribute("center_point"))
+ aCenter2 = geomDataAPI_Point2D(theArc2.attribute("center_point"))
+ aDistance = model.distancePointPoint(aCenter1, aCenter2)
aRadius1 = arcRadius(theArc1)
aRadius2 = arcRadius(theArc2)
aRadSum = aRadius1 + aRadius2
return math.fabs(aDistance - aRadSum) < theTolerance or math.fabs(aDistance - aRadDiff) < theTolerance
def arcRadius(theArc):
- aCenter = geomDataAPI_Point2D(theArc.attribute("ArcCenter"))
- aStart = geomDataAPI_Point2D(theArc.attribute("ArcStartPoint"))
- return distancePointPoint(aCenter, aStart)
-
-def distancePointPoint(thePoint1, thePoint2):
- return math.hypot(thePoint1.x() - thePoint2.x(), thePoint1.y() - thePoint2.y())
+ aCenter = geomDataAPI_Point2D(theArc.attribute("center_point"))
+ aStart = geomDataAPI_Point2D(theArc.attribute("start_point"))
+ return model.distancePointPoint(aCenter, aStart)
def distancePointLine(thePoint, theLine):
aLineStart = geomDataAPI_Point2D(theLine.attribute("StartPoint"))
aLineEnd = geomDataAPI_Point2D(theLine.attribute("EndPoint"))
- aLength = distancePointPoint(aLineStart, aLineEnd)
+ aLength = model.distancePointPoint(aLineStart, aLineEnd)
aDir1x, aDir1y = aLineEnd.x() - aLineStart.x(), aLineEnd.y() - aLineStart.y()
aDir2x, aDir2y = thePoint.x() - aLineStart.x(), thePoint.y() - aLineStart.y()
aCross = aDir1x * aDir2y - aDir1y * aDir2x
--- /dev/null
+"""
+ TestConstraintMirror.py
+ Unit test of SketchPlugin_ConstraintMirror class
+
+ SketchPlugin_ConstraintMirror
+ static const std::string MY_CONSTRAINT_MIRROR_ID("SketchConstraintMirror");
+ data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::typeId());
+ data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefListAttr::typeId());
+ data()->addAttribute(SketchPlugin_Constraint::ENTITY_C(), ModelAPI_AttributeRefListAttr::typeId());
+
+"""
+from GeomDataAPI import *
+from ModelAPI import *
+import math
+from salome.shaper import model
+
+#=========================================================================
+# Initialization of the test
+#=========================================================================
+
+__updated__ = "2015-03-17"
+
+#=========================================================================
+# Auxiliary functions
+#=========================================================================
+def normalize(theDir):
+ aLen = math.hypot(theDir[0], theDir[1])
+ if aLen < 1.e-10:
+ aLen = 1.0
+ return [theDir[0] / aLen, theDir[1] / aLen]
+
+def checkMirror(theListInit, theListMirr, theMirrorLine):
+ TOL = 6.e-5
+ aListSize = theListInit.size()
+
+ aLineStartPoint = geomDataAPI_Point2D(theMirrorLine.attribute("StartPoint"))
+ aLineEndPoint = geomDataAPI_Point2D(theMirrorLine.attribute("EndPoint"))
+ aLineDir = [aLineEndPoint.x() - aLineStartPoint.x(), aLineEndPoint.y() - aLineStartPoint.y()]
+ aLineDir = normalize(aLineDir)
+
+ for ind in range(0, aListSize):
+ aFeatureB = ModelAPI_Feature.feature(theListInit.object(ind))
+ aFeatureC = ModelAPI_Feature.feature(theListMirr.object(ind))
+ assert(aFeatureB is not None)
+ assert(aFeatureC is not None)
+ assert(aFeatureB.getKind() == aFeatureC.getKind())
+
+ anAttributes = []
+ if (aFeatureB.getKind() == "SketchLine"):
+ anAttributes = ['StartPoint', 'EndPoint']
+ elif (aFeatureB.getKind() == "SketchArc"):
+ anAttributes = ['center_point', 'start_point', 'end_point']
+
+ for key in anAttributes:
+ aPointB = geomDataAPI_Point2D(aFeatureB.attribute(key))
+ aPointC = geomDataAPI_Point2D(aFeatureC.attribute(key))
+ aDir = [aPointC.x() - aPointB.x(), aPointC.y() - aPointB.y()]
+ aDir = normalize(aDir)
+ aDot = aLineDir[0] * aDir[0] + aLineDir[1] * aDir[1]
+ assert math.fabs(aDot) < TOL, "aDot = {0}".format(aDot)
+ aDir[0] = aLineEndPoint.x() - 0.5 * (aPointB.x() + aPointC.x())
+ aDir[1] = aLineEndPoint.y() - 0.5 * (aPointB.y() + aPointC.y())
+ aCross = aLineDir[0] * aDir[1] - aLineDir[1] * aDir[0]
+ assert math.fabs(aCross) < TOL, "aCross = {0}".format(aCross)
+
+
+#=========================================================================
+# Start of test
+#=========================================================================
+aSession = ModelAPI_Session.get()
+aDocument = aSession.moduleDocument()
+#=========================================================================
+# Creation of a sketch
+#=========================================================================
+aSession.startOperation()
+aSketchCommonFeature = aDocument.addFeature("Sketch")
+aSketchFeature = featureToCompositeFeature(aSketchCommonFeature)
+origin = geomDataAPI_Point(aSketchFeature.attribute("Origin"))
+origin.setValue(0, 0, 0)
+dirx = geomDataAPI_Dir(aSketchFeature.attribute("DirX"))
+dirx.setValue(1, 0, 0)
+norm = geomDataAPI_Dir(aSketchFeature.attribute("Norm"))
+norm.setValue(0, 0, 1)
+aSession.finishOperation()
+#=========================================================================
+# Creation of an arc and two lines
+#=========================================================================
+# Arc
+aSession.startOperation()
+aSketchArc1 = aSketchFeature.addFeature("SketchArc")
+anArcCentr = geomDataAPI_Point2D(aSketchArc1.attribute("center_point"))
+anArcCentr.setValue(10., 10.)
+anArcStartPoint = geomDataAPI_Point2D(aSketchArc1.attribute("start_point"))
+anArcStartPoint.setValue(0., 50.)
+anArcEndPoint = geomDataAPI_Point2D(aSketchArc1.attribute("end_point"))
+anArcEndPoint.setValue(50., 0.)
+aSession.finishOperation()
+# Line 1
+aSession.startOperation()
+aSketchLine1 = aSketchFeature.addFeature("SketchLine")
+aLine1StartPoint = geomDataAPI_Point2D(aSketchLine1.attribute("StartPoint"))
+aLine1EndPoint = geomDataAPI_Point2D(aSketchLine1.attribute("EndPoint"))
+aLine1StartPoint.setValue(0., 50.)
+aLine1EndPoint.setValue(0., 100.)
+aSession.finishOperation()
+# Line 2
+aSession.startOperation()
+aSketchLine2 = aSketchFeature.addFeature("SketchLine")
+aLine2StartPoint = geomDataAPI_Point2D(aSketchLine2.attribute("StartPoint"))
+aLine2EndPoint = geomDataAPI_Point2D(aSketchLine2.attribute("EndPoint"))
+aLine2StartPoint.setValue(50., 0.)
+aLine2EndPoint.setValue(100., 0.)
+aSession.finishOperation()
+assert (model.dof(aSketchFeature) == 13)
+#=========================================================================
+# Link arc points and lines points by the coincidence constraint
+#=========================================================================
+aSession.startOperation()
+aConstraint = aSketchFeature.addFeature("SketchConstraintCoincidence")
+reflistA = aConstraint.refattr("ConstraintEntityA")
+reflistB = aConstraint.refattr("ConstraintEntityB")
+reflistA.setAttr(anArcStartPoint)
+reflistB.setAttr(aLine1StartPoint)
+aConstraint.execute()
+aSession.finishOperation()
+aSession.startOperation()
+aConstraint = aSketchFeature.addFeature("SketchConstraintCoincidence")
+reflistA = aConstraint.refattr("ConstraintEntityA")
+reflistB = aConstraint.refattr("ConstraintEntityB")
+reflistA.setAttr(anArcEndPoint)
+reflistB.setAttr(aLine2StartPoint)
+aConstraint.execute()
+aSession.finishOperation()
+assert (model.dof(aSketchFeature) == 9)
+#=========================================================================
+# Add tangency constraint and check correctness
+#=========================================================================
+aSession.startOperation()
+aTangency = aSketchFeature.addFeature("SketchConstraintTangent")
+aRefObjectA = aTangency.refattr("ConstraintEntityA")
+aRefObjectB = aTangency.refattr("ConstraintEntityB")
+anObjectA = modelAPI_ResultConstruction(aSketchArc1.lastResult())
+anObjectB = modelAPI_ResultConstruction(aSketchLine1.lastResult())
+assert (anObjectA is not None)
+assert (anObjectB is not None)
+aRefObjectA.setObject(anObjectA)
+aRefObjectB.setObject(anObjectB)
+aTangency.execute()
+aSession.finishOperation()
+assert (model.dof(aSketchFeature) == 8)
+#=========================================================================
+# Create mirror line
+#=========================================================================
+aSession.startOperation()
+aMirrorLine = aSketchFeature.addFeature("SketchLine")
+aLineStartPoint = geomDataAPI_Point2D(aMirrorLine.attribute("StartPoint"))
+aLineEndPoint = geomDataAPI_Point2D(aMirrorLine.attribute("EndPoint"))
+aLineStartPoint.setValue(100., 0.)
+aLineEndPoint.setValue(100., 100.)
+aSession.finishOperation()
+assert (model.dof(aSketchFeature) == 12)
+#=========================================================================
+# Make mirror for objects created above
+#=========================================================================
+aSession.startOperation()
+aMirror = aSketchFeature.addFeature("SketchConstraintMirror")
+aRefObjectA = aMirror.refattr("ConstraintEntityA")
+aRefObjectA.setObject(modelAPI_ResultConstruction(aMirrorLine.firstResult()))
+aRefListInitial = aMirror.reflist("ConstraintMirrorList")
+aRefListInitial.append(aSketchLine1.lastResult())
+aRefListInitial.append(aSketchArc1.lastResult())
+aRefListInitial.append(aSketchLine2.lastResult())
+aMirror.execute()
+aSession.finishOperation()
+assert (model.dof(aSketchFeature) == 12)
+#=========================================================================
+# Verify the simmetricity of all mirrored objects
+#=========================================================================
+aRefListB = aMirror.reflist("ConstraintEntityB")
+aRefListC = aMirror.reflist("ConstraintEntityC")
+assert (aRefListB.size() == 3)
+assert (aRefListC.size() == 3)
+checkMirror(aRefListB, aRefListC, aMirrorLine)
+assert (model.dof(aSketchFeature) == 12)
+
+#=========================================================================
+# Remove object from mirror
+#=========================================================================
+aSession.startOperation()
+aRefListInitial.remove(aSketchLine2.lastResult())
+aSession.finishOperation()
+assert (aRefListB.size() == 2)
+assert (aRefListC.size() == 2)
+checkMirror(aRefListB, aRefListC, aMirrorLine)
+assert (model.dof(aSketchFeature) == 12)
+
+#=========================================================================
+# Clear list of mirrored features
+#=========================================================================
+aSession.startOperation()
+aRefListInitial.clear()
+assert (aRefListB.size() == 0)
+assert (aRefListC.size() == 0)
+# add arc once again
+aRefListInitial.append(aSketchArc1.lastResult())
+aSession.finishOperation()
+assert (aRefListB.size() == 1)
+assert (aRefListC.size() == 1)
+checkMirror(aRefListB, aRefListC, aMirrorLine)
+assert (model.dof(aSketchFeature) == 12)
+
+#=========================================================================
+# Create distance between original and mirrored entities (check the error appears)
+#=========================================================================
+aSketchErrorAttr = aSketchFeature.string("SolverError")
+assert len(aSketchErrorAttr.value()) == 0, "Sketch failed with error: {}".format(aSketchErrorAttr.value())
+aMirroredArc = model.lastSubFeature(aSketchFeature, "SketchArc")
+aSession.startOperation()
+aConstraint = aSketchFeature.addFeature("SketchConstraintDistance")
+refAttrA = aConstraint.refattr("ConstraintEntityA")
+refAttrB = aConstraint.refattr("ConstraintEntityB")
+anArcStartPoint = geomDataAPI_Point2D(aSketchArc1.attribute("start_point"))
+aMirroredArcStartPoint = geomDataAPI_Point2D(aMirroredArc.attribute("start_point"))
+refAttrA.setAttr(anArcStartPoint)
+refAttrB.setAttr(aMirroredArcStartPoint)
+aConstraint.real("ConstraintValue").setValue(200.)
+aSession.finishOperation()
+print "Sketch error : {}".format(aSketchErrorAttr.value())
+assert len(aSketchErrorAttr.value()) != 0, "ERROR: Sketch has not been failed as expected"
+aSession.startOperation()
+aDocument.removeFeature(aConstraint)
+aSession.finishOperation()
+
+#=========================================================================
+# End of test
+#=========================================================================
+
+assert(model.checkPythonDump())
allFeatures = []
# Create arc
aSketchArc = theSketch.addFeature("SketchArc")
- aCenter = geomDataAPI_Point2D(aSketchArc.attribute("ArcCenter"))
- aStartPoint = geomDataAPI_Point2D(aSketchArc.attribute("ArcStartPoint"))
- aEndPoint = geomDataAPI_Point2D(aSketchArc.attribute("ArcEndPoint"))
+ aCenter = geomDataAPI_Point2D(aSketchArc.attribute("center_point"))
+ aStartPoint = geomDataAPI_Point2D(aSketchArc.attribute("start_point"))
+ aEndPoint = geomDataAPI_Point2D(aSketchArc.attribute("end_point"))
aCenter.setValue(5., 5.)
aStartPoint.setValue(10., 5.)
aEndPoint.setValue(5., 10.)
anAttributes.append('StartPoint')
anAttributes.append('EndPoint')
elif (feat.getKind() == "SketchArc"):
- anAttributes.append('ArcCenter')
- anAttributes.append('ArcStartPoint')
- anAttributes.append('ArcEndPoint')
+ anAttributes.append('center_point')
+ anAttributes.append('start_point')
+ anAttributes.append('end_point')
for attr in anAttributes:
aPoint1 = geomDataAPI_Point2D(feat.attribute(attr))
#=========================================================================
aSession.startOperation()
aRotationPoint = aSketchFeature.addFeature("SketchPoint")
-aRotationPointPoint = geomDataAPI_Point2D(aRotationPoint.attribute("PointCoordindates"))
+aRotationPointPoint = geomDataAPI_Point2D(aRotationPoint.attribute("PointCoordinates"))
aRotationPointPoint.setValue(CENTER_X, CENTER_Y)
aSession.finishOperation()
assert(model.dof(aSketchFeature) == 7)
allFeatures = []
# Create arc
aSketchArc = theSketch.addFeature("SketchArc")
- aCenter = geomDataAPI_Point2D(aSketchArc.attribute("ArcCenter"))
- aStartPoint = geomDataAPI_Point2D(aSketchArc.attribute("ArcStartPoint"))
- aEndPoint = geomDataAPI_Point2D(aSketchArc.attribute("ArcEndPoint"))
+ aCenter = geomDataAPI_Point2D(aSketchArc.attribute("center_point"))
+ aStartPoint = geomDataAPI_Point2D(aSketchArc.attribute("start_point"))
+ aEndPoint = geomDataAPI_Point2D(aSketchArc.attribute("end_point"))
aCenter.setValue(5., 5.)
aStartPoint.setValue(10., 5.)
aEndPoint.setValue(5., 10.)
anAttributes.append('StartPoint')
anAttributes.append('EndPoint')
elif (feat.getKind() == "SketchArc"):
- anAttributes.append('ArcCenter')
- anAttributes.append('ArcStartPoint')
- anAttributes.append('ArcEndPoint')
+ anAttributes.append('center_point')
+ anAttributes.append('start_point')
+ anAttributes.append('end_point')
for attr in anAttributes:
aPoint1 = geomDataAPI_Point2D(feat.attribute(attr))
aLineEnd.setValue(40., 30.)
aCircle = aSketchFeature.addFeature("SketchCircle")
-aCircleCenter = geomDataAPI_Point2D(aCircle.attribute("CircleCenter"))
-aCircleRadius = aCircle.real("CircleRadius")
+aCircleCenter = geomDataAPI_Point2D(aCircle.attribute("circle_center"))
+aCircleRadius = aCircle.real("circle_radius")
aCircleCenter.setValue(-25., -25)
aCircleRadius.setValue(25.)
anArc = aSketchFeature.addFeature("SketchArc")
-anArcCenter = geomDataAPI_Point2D(anArc.attribute("ArcCenter"))
-anArcStart = geomDataAPI_Point2D(anArc.attribute("ArcStartPoint"))
-anArcEnd = geomDataAPI_Point2D(anArc.attribute("ArcEndPoint"))
+anArcCenter = geomDataAPI_Point2D(anArc.attribute("center_point"))
+anArcStart = geomDataAPI_Point2D(anArc.attribute("start_point"))
+anArcEnd = geomDataAPI_Point2D(anArc.attribute("end_point"))
anArcCenter.setValue(10., 10.)
anArcStart.setValue(50., 0.)
anArcEnd.setValue(0., 50.)
aProjCircle = ModelAPI_Feature.feature(aCircleProjector.refattr("ProjectedFeature").object())
assert(aProjCircle)
-aProjCircleCenter = geomDataAPI_Point2D(aProjCircle.attribute("CircleCenter"))
-aProjCircleRadius = aProjCircle.real("CircleRadius")
+aProjCircleCenter = geomDataAPI_Point2D(aProjCircle.attribute("circle_center"))
+aProjCircleRadius = aProjCircle.real("circle_radius")
assert(math.fabs(aProjCircleCenter.x() - aCircleCenter.x()) < 1.e-10)
assert(math.fabs(aProjCircleCenter.y() - aCircleCenter.y()) < 1.e-10)
assert(math.fabs(aProjCircleRadius.value() - aCircleRadius.value()) < 1.e-10)
aProjArc = ModelAPI_Feature.feature(anArcProjector.refattr("ProjectedFeature").object())
-aProjArcCenter = geomDataAPI_Point2D(aProjArc.attribute("ArcCenter"))
-aProjArcStart = geomDataAPI_Point2D(aProjArc.attribute("ArcStartPoint"))
-aProjArcEnd = geomDataAPI_Point2D(aProjArc.attribute("ArcEndPoint"))
+aProjArcCenter = geomDataAPI_Point2D(aProjArc.attribute("center_point"))
+aProjArcStart = geomDataAPI_Point2D(aProjArc.attribute("start_point"))
+aProjArcEnd = geomDataAPI_Point2D(aProjArc.attribute("end_point"))
assert(math.fabs(aProjArcCenter.x() - anArcCenter.x()) < 1.e-10)
assert(math.fabs(aProjArcCenter.y() - anArcCenter.y()) < 1.e-10)
assert(math.fabs(aProjArcStart.x() - anArcStart.x()) < 1.e-10)
# aSketchPoint = aDocument.addFeature("SketchPoint")
aSketchPoint = aSketchFeature.addFeature("SketchPoint")
assert (aSketchPoint.getKind() == "SketchPoint")
-coords = geomDataAPI_Point2D(aSketchPoint.attribute("PointCoordindates"))
+coords = geomDataAPI_Point2D(aSketchPoint.attribute("PointCoordinates"))
assert (not coords.isInitialized())
# Simulate SketchPlugin_Point::move(...)
coords.setValue(10., 10.)
aSketchReflist = aSketchFeature.reflist("Features")
assert (aSketchReflist.size() == 1)
assert (len(aSketchReflist.list()) == 1)
-coords = geomDataAPI_Point2D(aSketchPoint.attribute("PointCoordindates"))
+coords = geomDataAPI_Point2D(aSketchPoint.attribute("PointCoordinates"))
assert (coords.x() == 10.0)
assert (coords.y() == 10.0)
#=========================================================================
--- /dev/null
+from salome.shaper import model
+
+from ModelAPI import *
+from GeomDataAPI import *
+from ModelGeomAlgo import ModelGeomAlgo_Point2D
+from salome.shaper import geom
+import math
+
+TOLERANCE = 1.e-7
+
+SketchLineId = 'SketchLine'
+SketchArcId = 'SketchArc'
+SketchConstraintCoincidenceId = 'SketchConstraintCoincidence'
+SketchConstraintEqualId = 'SketchConstraintEqual'
+
+aSession = ModelAPI_Session.get()
+model.begin()
+partSet = model.moduleDocument()
+Part = model.addPart(partSet)
+Part_doc = Part.document()
+
+# Test1:begin split on arc with coincident point and intersection line : smaller part
+Sketch = model.addSketch(Part_doc, model.defaultPlane("XOY"))
+SketchArc_1 = Sketch.addArc(50, 50, 30, 50, 50, 70, False)
+SketchArc_2 = Sketch.addArc(75, 80, 50, 70, 100, 100, True)
+SketchLine = Sketch.addLine(60, 31, 60, 130)
+SketchLine_2 = Sketch.addLine(10, 40, 90, 40)
+
+# correct start point of SketchLine to belong the arc for trim
+Intersected_Points = ModelGeomAlgo_Point2D.getSetOfPntIntersectedShape(SketchArc_1.feature(), FeatureList([SketchLine.feature()]))
+assert(len(Intersected_Points) == 2)
+if Intersected_Points[0].y() < Intersected_Points[1].y():
+ IntersectionPoint = Intersected_Points[0]
+else:
+ IntersectionPoint = Intersected_Points[1]
+
+SketchLine.startPoint().setValue(IntersectionPoint.x(), IntersectionPoint.y())
+
+SketchConstraintCoincidence_1_1 = Sketch.setCoincident(SketchArc_1.endPoint(), SketchArc_2.startPoint())
+SketchConstraintCoincidence_1_2 = Sketch.setCoincident(SketchArc_1.results()[1], SketchLine.startPoint())
+model.do()
+
+
+#find point on arc, where to perform trim
+SketchLine_intersecting = Sketch.addLine(50, 50, 100, 0)
+Geom_Points = ModelGeomAlgo_Point2D.getSetOfPntIntersectedShape(SketchArc_1.feature(), FeatureList([SketchLine_intersecting.feature()]))
+assert(len(Geom_Points) == 1)
+ModelAPI.removeFeaturesAndReferences(FeatureSet([SketchLine_intersecting.feature()]))
+model.do()
+GeomPoint = Geom_Points[0]
+
+model.do()
+SketchTrim = Sketch.addTrim(SketchArc_1, Sketch.to2D(GeomPoint))
+SketchTrim.execute()
+
+
+# Another case
+#GeomPoint = geom.Pnt2d(60, 50)
+#model.do()
+#SketchTrim = Sketch.addTrim(SketchArc_1, GeomPoint)
+#SketchTrim.execute()
+
+
+model.end()
+
+#assert(model.checkPythonDump())
assert(idList_after.count(SketchLineId) == 3)
assert(idList_after.count(SketchConstraintCoincidenceId) == 2)
-#check if line points are the same
-assert(SketchLine_1.startPoint().x() == 200)
-assert(SketchLine_1.startPoint().y() == 20)
-assert(SketchLine_1.endPoint().x() == 20)
-assert(SketchLine_1.endPoint().y() == 70)
-
-assert(SketchLine_3.startPoint().x() == -10)
-assert(SketchLine_3.startPoint().y() == 190)
-assert(SketchLine_3.endPoint().x() == 90)
-assert(SketchLine_3.endPoint().y() == 50)
-
model.end()
#assert(model.checkPythonDump())
--- /dev/null
+from salome.shaper import model
+
+from ModelAPI import *
+from GeomDataAPI import *
+from ModelGeomAlgo import ModelGeomAlgo_Point2D
+from salome.shaper import geom
+import math
+
+TOLERANCE = 1.e-7
+
+SketchLineId = 'SketchLine'
+SketchConstraintCoincidenceId = 'SketchConstraintCoincidence'
+
+aSession = ModelAPI_Session.get()
+model.begin()
+partSet = model.moduleDocument()
+Part = model.addPart(partSet)
+Part_doc = Part.document()
+
+# Test1:begin split on arc with coincident point and intersection line : smaller part
+Sketch = model.addSketch(Part_doc, model.defaultPlane("XOZ"))
+# Test of inverted Arc
+SketchLine_1 = Sketch.addLine(10, 80, 40, 10)
+SketchLine_2 = Sketch.addLine(40, 10, 70, 80)
+SketchLine_3 = Sketch.addLine(70, 80, 100, 10)
+SketchLine_4 = Sketch.addLine(100, 10, 130, 80)
+
+SketchLine_intersecting = Sketch.addLine(10, 50, 130, 50)
+
+SketchConstraintCoincidence_1_1 = Sketch.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchConstraintCoincidence_1_2 = Sketch.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_1_3 = Sketch.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+
+GeomPoint = geom.Pnt2d(40, 50)
+
+#check number of features before trim
+Sketch_feature = featureToCompositeFeature(Sketch.feature())
+idList_before = []
+for index in range(Sketch_feature.numberOfSubs()):
+ idList_before.append(Sketch_feature.subFeature(index).getKind())
+
+assert(idList_before.count(SketchLineId) == 5)
+assert(idList_before.count(SketchConstraintCoincidenceId) == 3)
+
+#perform trim
+SketchTrim = Sketch.addTrim(SketchLine_intersecting, GeomPoint)
+SketchTrim.execute()
+model.do()
+
+#check number of features after trim
+SketchFeatures = featureToCompositeFeature(Sketch.feature())
+idList_after = []
+
+LinesList = FeatureList()
+for SubIndex in range(SketchFeatures.numberOfSubs()):
+ SubFeature = SketchFeatures.subFeature(SubIndex)
+ idList_after.append(SubFeature.getKind())
+ if SubFeature.getKind() == SketchLineId:
+ LinesList.append(SubFeature)
+
+assert(idList_after.count(SketchLineId) == 6)
+assert(idList_after.count(SketchConstraintCoincidenceId) == 5)
+
+
+#check lines intersection to the source line
+SketchLine_intersecting_1 = Sketch.addLine(15, 55, 15, 40)
+SketchLine_intersecting_2 = Sketch.addLine(40, 55, 40, 40)
+SketchLine_intersecting_3 = Sketch.addLine(70, 55, 70, 40)
+SketchLine_intersecting_4 = Sketch.addLine(100, 55, 100, 40)
+SketchLine_intersecting_5 = Sketch.addLine(125, 55, 125, 40)
+
+Intersection_Points_1 = ModelGeomAlgo_Point2D.getSetOfPntIntersectedShape(SketchLine_intersecting_1.feature(), LinesList)
+Intersection_Points_2 = ModelGeomAlgo_Point2D.getSetOfPntIntersectedShape(SketchLine_intersecting_2.feature(), LinesList)
+Intersection_Points_3 = ModelGeomAlgo_Point2D.getSetOfPntIntersectedShape(SketchLine_intersecting_3.feature(), LinesList)
+Intersection_Points_4 = ModelGeomAlgo_Point2D.getSetOfPntIntersectedShape(SketchLine_intersecting_4.feature(), LinesList)
+Intersection_Points_5 = ModelGeomAlgo_Point2D.getSetOfPntIntersectedShape(SketchLine_intersecting_5.feature(), LinesList)
+
+assert(len(Intersection_Points_1) == 1)
+assert(len(Intersection_Points_2) == 0)
+assert(len(Intersection_Points_3) == 1)
+assert(len(Intersection_Points_4) == 1)
+assert(len(Intersection_Points_5) == 1)
+
+#check if line points are the same
+
+model.end()
+
+#assert(model.checkPythonDump())
<!-- SketchPoint -->
<feature id="SketchPoint" title="Point" tooltip="Create point" icon="icons/Sketch/point.png">
- <sketch-2dpoint_selector id="PointCoordindates" accept_expressions="0" title="Point" tooltip="Point coordinates"
+ <sketch-2dpoint_selector id="PointCoordinates" accept_expressions="0" title="Point" tooltip="Point coordinates"
enable_value="enable_by_preferences"/>
<boolvalue id="Auxiliary" label="Auxiliary" default="false" tooltip="Construction element" obligatory="0"/>
</feature>
icon="icons/Sketch/circle.png"
title="Circle"
tooltip="Create circle">
- <toolbox id="circle_type" modified_in_edit="false">
+ <toolbox id="circle_type" modified_in_edit="edit_circle_type">
<box id="circle_type_by_center_and_passed_points"
icon="icons/Sketch/circle_pt_rad_32x32.png"
title="Center and passed points">
title="Arc"
tooltip="Create arc"
icon="icons/Sketch/arc.png">
- <toolbox id="arc_type">
+ <toolbox id="arc_type" modified_in_edit="edit_arc_type">
<box id="by_center_and_points"
icon="icons/Sketch/arc_base_32x32.png"
title="Center and two points">
accept_expressions="0"
enable_value="enable_by_preferences">
<validator id="SketchPlugin_DifferentReference" parameters="start_point_ref,end_point_ref"/>
- <validator id="SketchPlugin_ArcEndPointValidator" parameters="end_point_ref"/>
</sketch-2dpoint_selector>
<sketch-2dpoint_selector id="passed_point"
reference_attribute="passed_point_ref"
icon="icons/Sketch/split.png">
<sketch_sub_shape_selector
id="ConstraintValue"
- label="Split feature"
- tooltip="Select feature for split"
+ label="Segment"
+ tooltip="Select segment for split"
shape_types="edge"
use_external="false"
use_graphic_intersection="false">
icon="icons/Sketch/trim.png">
<sketch_feature_point_selector
id="SelectedObject"
- label="Split feature"
- tooltip="Select feature for split"
+ label="Segment"
+ tooltip="Select segment for trim"
shape_types="edge"
use_external="false"
use_graphic_intersection="true">
PlaneGCSSolver_Solver::PlaneGCSSolver_Solver()
: myEquationSystem(new GCS::System),
+ myDiagnoseBeforeSolve(false),
myConfCollected(false),
myDOF(0)
{
{
double* aResult = new double(0);
myParameters.push_back(aResult);
- if (myDOF >= 0)
- ++myDOF;
+ if (myConstraints.empty() && myDOF >= 0)
+ ++myDOF; // calculate DoF by hand if and only if there is no constraints yet
+ else
+ myDiagnoseBeforeSolve = true;
return aResult;
}
return STATUS_INCONSISTENT;
Events_LongOp::start(this);
+ if (myDiagnoseBeforeSolve)
+ diagnose();
// solve equations
GCS::SolveStatus aResult = (GCS::SolveStatus)myEquationSystem->solve(myParameters);
Events_LongOp::end(this);
- GCS::VEC_I aRedundant;
- myEquationSystem->getRedundant(aRedundant);
- if (!aRedundant.empty()) {
- collectConflicting();
- if (!myConflictingIDs.empty())
- aResult = GCS::Failed;
- }
+ // collect information about conflicting constraints every time,
+ // sometimes solver reports about succeeded recalculation but has conflicting constraints
+ // (for example, apply horizontal constraint for a copied feature)
+ collectConflicting();
+ if (!myConflictingIDs.empty())
+ aResult = GCS::Failed;
SolveStatus aStatus;
if (aResult == GCS::Failed)
int PlaneGCSSolver_Solver::dof()
{
if (myDOF < 0 && !myConstraints.empty())
- solve();
+ diagnose();
return myDOF;
}
+
+void PlaneGCSSolver_Solver::diagnose()
+{
+ myEquationSystem->declareUnknowns(myParameters);
+ myDOF = myEquationSystem->diagnose();
+ myDiagnoseBeforeSolve = false;
+}
/// \brief Check the constraint is conflicted with others
bool isConflicting(const ConstraintID& theConstraint) const;
+ /// \brief Check conflicting/redundant constraints and DoF
+ void diagnose();
+
/// \brief Degrees of freedom
int dof();
ConstraintMap myConstraints; ///< list of constraints
std::shared_ptr<GCS::System> myEquationSystem; ///< set of equations for solving in FreeGCS
+ bool myDiagnoseBeforeSolve; ///< is the diagnostic necessary
GCS::SET_I myConflictingIDs; ///< list of IDs of conflicting constraints
-
/// specifies the conflicting constraints are already collected
bool myConfCollected;
if (myConstraintMap.empty())
return; // no need to process temporary constraints if there is no active constraint
+ // before adding movement constraint to solver, re-check its DOF
+ if (mySketchSolver->dof() == 0)
+ mySketchSolver->diagnose();
+
theSolverConstraint->setId(CID_MOVEMENT);
constraintsToSolver(theSolverConstraint, mySketchSolver);
}
bool PlaneGCSSolver_Storage::update(FeaturePtr theFeature, bool theForce)
{
+ bool sendNotify = false;
bool isUpdated = false;
EntityWrapperPtr aRelated = entity(theFeature);
if (aRelated) // send signal to subscribers
- notify(theFeature);
+ sendNotify = true;
else { // Feature is not exist, create it
std::shared_ptr<SketchPlugin_Feature> aSketchFeature =
std::dynamic_pointer_cast<SketchPlugin_Feature>(theFeature);
(*anAttrIt)->attributeType() == ModelAPI_AttributeDouble::typeId())
isUpdated = update(*anAttrIt) || isUpdated;
+ // send notification to listeners due to at least one attribute is changed
+ if (sendNotify && isUpdated)
+ notify(theFeature);
+
// update arc
if (aRelated && aRelated->type() == ENTITY_ARC) {
/// TODO: this code should be shared with FeatureBuilder somehow
}
// indicates attribute containing in the external feature
-bool isExternalAttribute(const AttributePtr& theAttribute)
+static bool isExternalAttribute(const AttributePtr& theAttribute)
{
if (!theAttribute)
return false;
return aSketchFeature.get() && aSketchFeature->isExternal();
}
+static void addOwnerToSet(const AttributePtr& theAttribute, std::set<FeaturePtr>& theFeatures)
+{
+ FeaturePtr anOwner = ModelAPI_Feature::feature(theAttribute->owner());
+ if (anOwner)
+ theFeatures.insert(anOwner);
+}
+
void PlaneGCSSolver_Storage::refresh() const
{
const double aTol = 1000. * tolerance; // tolerance to prevent frequent updates
+ std::set<FeaturePtr> anUpdatedFeatures;
+
std::map<AttributePtr, EntityWrapperPtr>::const_iterator anIt = myAttributeMap.begin();
for (; anIt != myAttributeMap.end(); ++anIt) {
// the external feature always should keep the up to date values, so,
std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(anIt->second);
GCSPointPtr aGCSPoint = aPointWrapper->point();
if (fabs(aPoint2D->x() - (*aGCSPoint->x)) > aTol ||
- fabs(aPoint2D->y() - (*aGCSPoint->y)) > aTol)
+ fabs(aPoint2D->y() - (*aGCSPoint->y)) > aTol) {
aPoint2D->setValue(*aGCSPoint->x, *aGCSPoint->y);
+ addOwnerToSet(anIt->first, anUpdatedFeatures);
+ }
continue;
}
AttributeDoublePtr aScalar = std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(anIt->first);
if (aScalar) {
ScalarWrapperPtr aScalarWrapper =
std::dynamic_pointer_cast<PlaneGCSSolver_ScalarWrapper>(anIt->second);
- if (fabs(aScalar->value() - aScalarWrapper->value()) > aTol)
+ if (fabs(aScalar->value() - aScalarWrapper->value()) > aTol) {
aScalar->setValue(aScalarWrapper->value());
+ addOwnerToSet(anIt->first, anUpdatedFeatures);
+ }
continue;
}
}
+
+ // notify listeners about features update
+ std::set<FeaturePtr>::const_iterator aFIt = anUpdatedFeatures.begin();
+ for (; aFIt != anUpdatedFeatures.end(); ++aFIt)
+ notify(*aFIt);
}
/// \brief Remove all features became invalid
virtual void removeInvalidEntities();
+ /// \brief Check the storage has constraints
+ virtual bool isEmpty() const
+ { return SketchSolver_Storage::isEmpty() && myArcConstraintMap.empty(); }
+
private:
/// \brief Convert feature using specified builder.
EntityWrapperPtr createFeature(const FeaturePtr& theFeature,
}
bool isNew = false;
- for (int i = 0; i < 4 && !isNew; ++i)
+ for (int i = 0; i < 4; ++i) {
if (aConstraintToApply[i] != myIsConstraintApplied[i])
isNew = true;
+ myIsConstraintApplied[i] = aConstraintToApply[i];
+ }
+
if (isNew) {
mySolverConstraint = createPointsOnLine(aPoints[0], aPoints[1], aLine);
- myStorage->removeConstraint(myBaseConstraint);
- myStorage->addConstraint(myBaseConstraint, mySolverConstraint);
+ if (myInSolver) {
+ myStorage->removeConstraint(myBaseConstraint);
+ myInSolver = false;
+ }
+ if (mySolverConstraint) {
+ myStorage->addConstraint(myBaseConstraint, mySolverConstraint);
+ myInSolver = true;
+ }
}
}
public:
/// Constructor based on SketchPlugin constraint
SketchSolver_ConstraintCollinear(ConstraintPtr theConstraint)
- : SketchSolver_Constraint(theConstraint)
+ : SketchSolver_Constraint(theConstraint),
+ myInSolver(false)
{
for (int i = 0; i < 4; ++i)
myIsConstraintApplied[i] = false;
private:
EntityWrapperPtr myPoints[4]; ///< extremities on collinear lines
bool myIsConstraintApplied[4]; ///< set \c true if point on opposite line
+ bool myInSolver; ///< the constraint is added to the solver
};
#endif
#include <PlaneGCSSolver_PointWrapper.h>
#include <GeomDataAPI_Point2D.h>
+#include <SketchPlugin_Feature.h>
#include <cmath>
std::vector<EntityWrapperPtr>& theAttributes)
{
if (myBaseFeature) {
+ // if the feature is copy, do not move it
+ std::shared_ptr<SketchPlugin_Feature> aSketchFeature =
+ std::dynamic_pointer_cast<SketchPlugin_Feature>(myBaseFeature);
+ if (aSketchFeature && aSketchFeature->isCopy()) {
+ myStorage->setNeedToResolve(true);
+ return;
+ }
+
// The feature is fixed.
EntityWrapperPtr aSolverEntity = getChangedEntity(myBaseFeature, myStorage);
myStorage->update(myBaseFeature);
for (; aPIt != aPoints.end(); ++aPIt) {
AttributePoint2DPtr aPnt = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(*aPIt);
EntityWrapperPtr anEnt = theStorage->entity(*aPIt);
- if (!anEnt)
- continue;
- PointWrapperPtr aPW = std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(anEnt);
- if (!isSameCoordinates(aPnt, aPW))
- aChangedPoints.push_back(anEnt);
+ if (anEnt) {
+ PointWrapperPtr aPW = std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(anEnt);
+ if (!isSameCoordinates(aPnt, aPW))
+ aChangedPoints.push_back(anEnt);
+ } else {
+ theStorage->update(*aPIt);
+ aChangedPoints.push_back(theStorage->entity(*aPIt));
+ }
}
EntityWrapperPtr aChanged;
FeaturePtr aBase = ModelAPI_Feature::feature(*aBIt);
FeaturePtr aMirrored = ModelAPI_Feature::feature(*aMIt);
mirrorEntities(aMirrorLine, aBase, aMirrored);
+
+ // update mirrored entity if it exists in the storage
+ if (myStorage->entity(aMirrored))
+ myStorage->update(aMirrored);
}
}
theAngle = aValueBuilder.createAttribute(anAngleAttr);
myStorage->addEntity(anAngleAttr, theAngle);
- AttributePtr aCenterAttr = myBaseConstraint->attribute(SketchPlugin_MultiRotation::CENTER_ID());
+ AttributeRefAttrPtr aCenterAttr =
+ myBaseConstraint->refattr(SketchPlugin_MultiRotation::CENTER_ID());
if (!aCenterAttr || !aCenterAttr->isInitialized()) {
myErrorMsg = SketchSolver_Error::NOT_INITIALIZED();
return;
myType = CONSTRAINT_MULTI_ROTATION;
- myStorage->update(aCenterAttr);
- theCenter = myStorage->entity(aCenterAttr);
+ myStorage->update(AttributePtr(aCenterAttr));
+ theCenter = myStorage->entity(AttributePtr(aCenterAttr));
AttributeStringPtr aMethodTypeAttr =
myBaseConstraint->string(SketchPlugin_MultiRotation::ANGLE_TYPE());
theFullValue = aMethodTypeAttr->value() != "SingleAngle";
getEntities(theEntities);
+
+ // add owner of central point of Multi-Rotation to the list of monitored features
+ FeaturePtr anOwner = ModelAPI_Feature::feature(aCenterAttr->attr()->owner());
+ if (anOwner)
+ myFeatures.insert(anOwner);
}
void SketchSolver_ConstraintMultiRotation::process()
bool& theFullValue, std::list<EntityWrapperPtr>& theEntities)
{
DataPtr aData = myBaseConstraint->data();
- AttributePtr aStartPointAttr = aData->attribute(SketchPlugin_MultiTranslation::START_POINT_ID());
- AttributePtr aEndPointAttr = aData->attribute(SketchPlugin_MultiTranslation::END_POINT_ID());
+ AttributeRefAttrPtr aStartPointAttr =
+ aData->refattr(SketchPlugin_MultiTranslation::START_POINT_ID());
+ AttributeRefAttrPtr aEndPointAttr =
+ aData->refattr(SketchPlugin_MultiTranslation::END_POINT_ID());
if (!aStartPointAttr || !aStartPointAttr->isInitialized() ||
!aEndPointAttr || !aEndPointAttr->isInitialized()) {
myErrorMsg = SketchSolver_Error::NOT_INITIALIZED();
myType = CONSTRAINT_MULTI_TRANSLATION;
- myStorage->update(aStartPointAttr);
- theStartPoint = myStorage->entity(aStartPointAttr);
- myStorage->update(aEndPointAttr);
- theEndPoint = myStorage->entity(aEndPointAttr);
+ myStorage->update(AttributePtr(aStartPointAttr));
+ theStartPoint = myStorage->entity(AttributePtr(aStartPointAttr));
+ myStorage->update(AttributePtr(aEndPointAttr));
+ theEndPoint = myStorage->entity(AttributePtr(aEndPointAttr));
AttributeStringPtr aMethodTypeAttr = aData->string(SketchPlugin_MultiTranslation::VALUE_TYPE());
theFullValue = aMethodTypeAttr->value() != "SingleValue";
getEntities(theEntities);
+
+ // add owner of start and end points of Multi-Translation to the list of monitored features
+ FeaturePtr anOwner = ModelAPI_Feature::feature(aStartPointAttr->attr()->owner());
+ if (anOwner)
+ myFeatures.insert(anOwner);
+ anOwner = ModelAPI_Feature::feature(aEndPointAttr->attr()->owner());
+ if (anOwner)
+ myFeatures.insert(anOwner);
}
void SketchSolver_ConstraintMultiTranslation::process()
std::shared_ptr<GCS::Circle> aCirc =
std::dynamic_pointer_cast<GCS::Circle>(anEntCirc->entity());
+ std::shared_ptr<GCS::Arc> anArc = std::dynamic_pointer_cast<GCS::Arc>(aCirc);
+
std::shared_ptr<GCS::Line> aLine =
std::dynamic_pointer_cast<GCS::Line>(anEntLine->entity());
GCSConstraintPtr aNewConstr;
- if (theSharedPoint) {
- std::shared_ptr<GCS::Arc> anArc = std::dynamic_pointer_cast<GCS::Arc>(aCirc);
+ if (theSharedPoint && anArc) { // do not process shared point between circle and line
GCSPointPtr aPoint =
std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(theSharedPoint)->point();
"To fix this, you can either undo your operation or remove a conflicting constraint.");
return MY_ERROR_VALUE;
}
+ /// Cyclic dependency of copied features with their originals
+ inline static const std::string& INFINITE_LOOP()
+ {
+ static const std::string MY_ERROR_VALUE(
+ "There is a circular reference between copied sketch entities and their originals. "
+ "To fix this, you can either undo your operation or remove wrong constraint.");
+ return MY_ERROR_VALUE;
+ }
/// Constraints should use objects instead of features as attributes
inline static const std::string& NEED_OBJECT_NOT_FEATURE()
{
#include <Events_InfoMessage.h>
#include <ModelAPI_AttributeString.h>
#include <ModelAPI_Events.h>
+#include <SketchPlugin_ConstraintMirror.h>
#include <SketchPlugin_ConstraintRigid.h>
+#include <SketchPlugin_MultiRotation.h>
+#include <SketchPlugin_MultiTranslation.h>
static void sendMessage(const char* theMessageName)
Events_Loop::loop()->send(aMessage);
}
-static void sendMessage(const char* theMessageName, const CompositeFeaturePtr& theSketch, const int theDOF)
+static void sendMessage(const char* theMessageName,
+ const CompositeFeaturePtr& theSketch,
+ const int theDOF)
{
std::shared_ptr<ModelAPI_SolverFailedMessage> aMessage =
std::shared_ptr<ModelAPI_SolverFailedMessage>(
: mySketch(theWorkplane),
myPrevResult(PlaneGCSSolver_Solver::STATUS_UNKNOWN),
myDOF(0),
- myIsEventsBlocked(false)
+ myIsEventsBlocked(false),
+ myMultiConstraintUpdateStack(0)
{
mySketchSolver = SolverPtr(new PlaneGCSSolver_Solver);
myStorage = StoragePtr(new PlaneGCSSolver_Storage(mySketchSolver));
}
else
myConstraints[theConstraint]->update();
+
+ // constraint is created/updated => reset stack of "multi" constraints updates
+ myMultiConstraintUpdateStack = 0;
return true;
}
bool SketchSolver_Group::moveFeature(FeaturePtr theFeature)
{
- if (myDOF == 0) {
+ bool isFeatureExists = (myStorage->entity(theFeature).get() != 0);
+ if (myDOF == 0 && isFeatureExists) {
// avoid moving elements of fully constrained sketch
myStorage->refresh();
return true;
// ============================================================================
bool SketchSolver_Group::resolveConstraints()
{
+ // check the "Multi" constraints do not drop sketch into infinite loop
+ if (myMultiConstraintUpdateStack > 1) {
+ myPrevResult = PlaneGCSSolver_Solver::STATUS_FAILED;
+ // generate error message due to loop update of the sketch
+ getWorkplane()->string(SketchPlugin_Sketch::SOLVER_ERROR())
+ ->setValue(SketchSolver_Error::INFINITE_LOOP());
+ sendMessage(EVENT_SOLVER_FAILED, myConflictingConstraints);
+ return false;
+ }
+
bool aResolved = false;
bool isGroupEmpty = isEmpty() && myStorage->isEmpty();
if (myStorage->isNeedToResolve() &&
PlaneGCSSolver_Solver::SolveStatus aResult = PlaneGCSSolver_Solver::STATUS_OK;
try {
- if (!isGroupEmpty)
+ if (!isGroupEmpty && myMultiConstraintUpdateStack <= 1)
aResult = mySketchSolver->solve();
} catch (...) {
getWorkplane()->string(SketchPlugin_Sketch::SOLVER_ERROR())
aResult == PlaneGCSSolver_Solver::STATUS_EMPTYSET) {
myStorage->setNeedToResolve(false);
myStorage->refresh();
-//// updateMultiConstraints(myConstraints);
-//// // multi-constraints updated some parameters, need to store them
-//// if (myStorage->isNeedToResolve())
-//// resolveConstraints();
- if (myPrevResult != PlaneGCSSolver_Solver::STATUS_OK ||
- myPrevResult == PlaneGCSSolver_Solver::STATUS_UNKNOWN) {
- getWorkplane()->string(SketchPlugin_Sketch::SOLVER_ERROR())->setValue("");
- std::set<ObjectPtr> aConflicting = myConflictingConstraints;
- myConflictingConstraints.clear();
- myPrevResult = PlaneGCSSolver_Solver::STATUS_OK;
- // the error message should be changed before sending the message
- sendMessage(EVENT_SOLVER_REPAIRED, aConflicting);
+ // additional check that copied entities used in Mirror and other "Multi" constraints
+ // is not connected with their originals by constraints.
+ myMultiConstraintUpdateStack += 1;
+ aResolved = true;
+ if (myStorage->isNeedToResolve())
+ aResolved = resolveConstraints();
+
+ if (aResolved) {
+ myMultiConstraintUpdateStack -= 1;
+
+ if (myPrevResult != PlaneGCSSolver_Solver::STATUS_OK ||
+ myPrevResult == PlaneGCSSolver_Solver::STATUS_UNKNOWN) {
+ getWorkplane()->string(SketchPlugin_Sketch::SOLVER_ERROR())->setValue("");
+ std::set<ObjectPtr> aConflicting = myConflictingConstraints;
+ myConflictingConstraints.clear();
+ myPrevResult = PlaneGCSSolver_Solver::STATUS_OK;
+ // the error message should be changed before sending the message
+ sendMessage(EVENT_SOLVER_REPAIRED, aConflicting);
+ }
}
// show degrees of freedom
}
}
- aResolved = true;
- } else if (!isGroupEmpty) {
- // Check if the group contains only constraints Fixed, update parameters by stored values
- aResolved = true;
- ConstraintConstraintMap::iterator aCIt = myConstraints.begin();
- for (; aCIt != myConstraints.end(); ++aCIt)
- if (aCIt->first->getKind() != SketchPlugin_ConstraintRigid::ID()) {
- aResolved = false;
- break;
- }
- if (aCIt == myConstraints.end())
- myStorage->refresh();
} else if (isGroupEmpty && isWorkplaneValid())
computeDoF();
removeTemporaryConstraints();
{
std::ostringstream aDoFMsg;
int aDoF = mySketchSolver->dof();
+ /// "DoF = 0" content of string value is used in PartSet by Sketch edit
+ /// If it is changed, it should be corrected also there
if (aDoF == 0)
aDoFMsg << "Sketch is fully fixed (DoF = 0)";
else
// ============================================================================
void SketchSolver_Group::repairConsistency()
{
- if (!myStorage->isConsistent()) {
+ if (!areConstraintsValid() || !myStorage->areFeaturesValid()) {
// remove invalid constraints
std::set<ConstraintPtr> anInvalidConstraints;
ConstraintConstraintMap::iterator aCIter = myConstraints.begin();
for (; aCIter != myConstraints.end(); aCIter++)
if (aCIter->first == theConstraint) {
aCIter->second->remove(); // the constraint is not fully removed
+
+ // constraint is removed => reset stack of "multi" constraints updates
+ myMultiConstraintUpdateStack = 0;
break;
}
if (aCIter != myConstraints.end())
myIsEventsBlocked = isBlocked;
}
+
+bool SketchSolver_Group::areConstraintsValid() const
+{
+ // Check the constraints are valid
+ ConstraintConstraintMap::const_iterator aCIter = myConstraints.begin();
+ for (; aCIter != myConstraints.end(); ++aCIter)
+ if (!aCIter->first->data() || !aCIter->first->data()->isValid())
+ return false;
+ return true;
+}
/// \brief Returns true if the group has no constraints yet
inline bool isEmpty() const
{
- return myConstraints.empty();
+ return myConstraints.empty() && myTempConstraints.empty();
}
/// \brief Check for valid sketch data
void blockEvents(bool isBlocked);
private:
+ /// \biref Verify constraints have not been removed
+ bool areConstraintsValid() const;
+
/** \brief Removes constraints from the group
* \param[in] theConstraint constraint to be removed
*/
int myDOF; ///< degrees of freedom of the current sketch
bool myIsEventsBlocked; ///< shows the events are blocked for this group
+
+ int myMultiConstraintUpdateStack; ///< depth of the stack updating "Multi" constraints
};
typedef std::shared_ptr<SketchSolver_Group> SketchGroupPtr;
void SketchSolver_Manager::processEvent(
const std::shared_ptr<Events_Message>& theMessage)
{
+ bool needToResolve = false;
+ bool isUpdateFlushed = false;
+ bool isMovedEvt = false;
+
static const Events_ID anUpdateEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED);
static const Events_ID aSketchPreparedEvent = Events_Loop::eventByName(EVENT_SKETCH_PREPARED);
// sketch is prepared for resolve: all the needed events
// are collected and must be processed by the solver
if (theMessage->eventID() == aSketchPreparedEvent) {
flushGrouped(anUpdateEvent);
- return;
+ needToResolve = true;
}
if (myIsComputed)
std::dynamic_pointer_cast<ModelAPI_ObjectUpdatedMessage>(theMessage);
std::set<ObjectPtr> aFeatures = anUpdateMsg->objects();
- bool isUpdateFlushed = stopSendUpdate();
+ isUpdateFlushed = stopSendUpdate();
- bool isMovedEvt = theMessage->eventID()
+ isMovedEvt = theMessage->eventID()
== Events_Loop::loop()->eventByName(EVENT_OBJECT_MOVED);
// Shows that the message has at least one feature applicable for solver
hasProperFeature = updateFeature(aFeature, isMovedEvt) || hasProperFeature;
}
- if (isMovedEvt && !hasProperFeature) {
- // in this iteration it will compute nothing, so, no problem with recursion
- // it is important that solver flushes signal updated after processing move signal as there
- // is optimization that relies on this update, might be found by key "optimization"
- myIsComputed = false;
- }
-
- // Solve the set of constraints
- bool needToUpdate = resolveConstraints();
-
- // Features may be updated => now send events, but for all changed at once
- if (isUpdateFlushed)
- allowSendUpdate();
-
- myIsComputed = false;
-
- // send update for movement in any case
- if (needToUpdate || isMovedEvt)
- Events_Loop::loop()->flush(anUpdateEvent);
+ if (isMovedEvt && hasProperFeature)
+ needToResolve = true;
} else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_DELETED)) {
std::shared_ptr<ModelAPI_ObjectDeletedMessage> aDeleteMsg =
(*aGroupIter)->repairConsistency();
++aGroupIter;
}
-
- resolveConstraints();
}
myIsComputed = false;
}
+
+ // resolve constraints if needed
+ bool needToUpdate = needToResolve && resolveConstraints();
+
+ // Features may be updated => now send events, but for all changed at once
+ if (isUpdateFlushed)
+ allowSendUpdate();
+
+ myIsComputed = false;
+
+ // send update for movement in any case
+ if (needToUpdate || isMovedEvt)
+ Events_Loop::loop()->flush(anUpdateEvent);
}
// ============================================================================
}
-bool SketchSolver_Storage::isConsistent() const
+bool SketchSolver_Storage::areFeaturesValid() const
{
- // Check the constraints are valid
- std::map<ConstraintPtr, ConstraintWrapperPtr>::const_iterator
- aCIter = myConstraintMap.begin();
- for (; aCIter != myConstraintMap.end(); ++aCIter)
- if (!aCIter->first->data() || !aCIter->first->data()->isValid())
- return false;
// Check the features are valid
std::map<FeaturePtr, EntityWrapperPtr>::const_iterator aFIter = myFeatureMap.begin();
for (; aFIter != myFeatureMap.end(); aFIter++)
/// \brief Remove all features became invalid
virtual void removeInvalidEntities() = 0;
- /// \brief Check the features is not removed
- bool isConsistent() const;
+ /// \brief Check the features have not been removed
+ bool areFeaturesValid() const;
/// \brief Check the storage has constraints
- bool isEmpty() const
+ virtual bool isEmpty() const
{ return myConstraintMap.empty(); }
/// \brief Shows the sketch should be resolved
<source>The constraint is conflicting with others. To fix this, you can either undo your operation or remove a conflicting constraint.</source>
<translation>The constraint is conflicting with others. To fix this, you can either undo your operation or remove a conflicting constraint.</translation>
</message>
+ <message>
+ <source>There is a circular reference between copied sketch entities and their originals. To fix this, you can either undo your operation or remove wrong constraint.</source>
+ <translation>There is a circular reference between copied sketch entities and their originals. To fix this, you can either undo your operation or remove wrong constraint.</translation>
+ </message>
<message>
<source>Caution: SolveSpace crash! Constraints are wrong</source>
<translation>Caution: SolveSpace crash! Constraints are wrong</translation>
SketcherPrs_Coincident::SketcherPrs_Coincident(ModelAPI_Feature* theConstraint,
const std::shared_ptr<GeomAPI_Ax3>& thePlane)
: AIS_InteractiveObject(), myConstraint(theConstraint), mySketcherPlane(thePlane),
- myPoint(gp_Pnt(0.0, 0.0, 0.0)), myIsConflicting(false)
+ myPoint(gp_Pnt(0.0, 0.0, 0.0)), myIsCustomColor(false)
{
}
myPoint = aPoint;
// Create the presentation as a combination of standard point markers
- bool aValid = !myIsConflicting;
+ bool aCustomColor = myIsCustomColor;
// The external yellow contour
Handle(Graphic3d_AspectMarker3d) aPtA = new Graphic3d_AspectMarker3d();
aPtA->SetType(Aspect_TOM_RING3);
aPtA->SetScale(2.);
- aPtA->SetColor(aValid ? Quantity_NOC_YELLOW : myConflictingColor);
+ aPtA->SetColor(!aCustomColor ? Quantity_NOC_YELLOW : myCustomColor);
Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup(thePresentation);
aGroup->SetPrimitivesAspect(aPtA);
aPtA = new Graphic3d_AspectMarker3d();
aPtA->SetType(Aspect_TOM_RING1);
aPtA->SetScale(1.);
- aPtA->SetColor(aValid ? Quantity_NOC_BLACK : myConflictingColor);
+ aPtA->SetColor(!aCustomColor ? Quantity_NOC_BLACK : myCustomColor);
aGroup->SetPrimitivesAspect(aPtA);
aGroup->AddPrimitiveArray (aPntArray);
aPtA = new Graphic3d_AspectMarker3d();
aPtA->SetType(Aspect_TOM_POINT);
aPtA->SetScale(5.);
- aPtA->SetColor(aValid ? Quantity_NOC_BLACK : myConflictingColor);
+ aPtA->SetColor(!aCustomColor ? Quantity_NOC_BLACK : myCustomColor);
aGroup->SetPrimitivesAspect(aPtA);
aGroup->AddPrimitiveArray (aPntArray);
myOwnColor=aCol;
}
-void SketcherPrs_Coincident::SetConflictingConstraint(const bool& theConflicting,
- const std::vector<int>& theColor)
+void SketcherPrs_Coincident::SetCustomColor(const std::vector<int>& theColor)
{
- myIsConflicting = theConflicting;
- myConflictingColor = Quantity_Color(theColor[0] / 255., theColor[1] / 255., theColor[2] / 255.,
- Quantity_TOC_RGB);
+ myIsCustomColor = !theColor.empty();
+ if (myIsCustomColor)
+ myCustomColor = Quantity_Color(theColor[0] / 255., theColor[1] / 255.,
+ theColor[2] / 255., Quantity_TOC_RGB);
+ else
+ myCustomColor = Quantity_Color();
}
/// \param aColor a color name
Standard_EXPORT virtual void SetColor(const Quantity_NameOfColor aColor);
- /// Set state of the presentation, in case of conflicting state, the icon of the presentation is
+ /// Set state of the presentation, in case of custom color, the icon of the presentation is
/// visualized in error color.
- /// The state is stored in an internal field, so should be changed when
- /// constraint become not conflicting
- /// \param theConflicting a state
- /// \param theColor a color for conflicting object
- Standard_EXPORT void SetConflictingConstraint(const bool& theConflicting,
- const std::vector<int>& theColor);
+ /// \param theColor a custom color for object presentation
+ Standard_EXPORT void SetCustomColor(const std::vector<int>& theColor);
/// Returns true if the constraint feature arguments are correcly filled to build AIS presentation
/// \param theConstraint a constraint feature
ModelAPI_Feature* myConstraint;
std::shared_ptr<GeomAPI_Ax3> mySketcherPlane;
gp_Pnt myPoint;
- bool myIsConflicting; /// state if the presentation is visualized in error state
- Quantity_Color myConflictingColor; /// the color of mid ring if there is a conflict
+ bool myIsCustomColor; /// state if the presentation is visualized in custom color
+ Quantity_Color myCustomColor; /// the color of mid ring if there is a conflict
};
const std::shared_ptr<GeomAPI_Ax3>& thePlane)
: SketcherPrs_SymbolPrs(theConstraint, thePlane)
{
- myPntArray = new Graphic3d_ArrayOfPoints(2);
- myPntArray->AddVertex(0., 0., 0.);
- myPntArray->AddVertex(0., 0., 0.);
}
bool SketcherPrs_Collinear::IsReadyToDisplay(ModelAPI_Feature* theConstraint,
return aReadyToDisplay;
}
-bool SketcherPrs_Collinear::updateIfReadyToDisplay(double theStep) const
+bool SketcherPrs_Collinear::updateIfReadyToDisplay(double theStep, bool withColor) const
{
if (!IsReadyToDisplay(myConstraint, myPlane))
return false;
SketcherPrs_PositionMgr* aMgr = SketcherPrs_PositionMgr::get();
gp_Pnt aP1 = aMgr->getPosition(aObj1, this, theStep);
gp_Pnt aP2 = aMgr->getPosition(aObj2, this, theStep);
- myPntArray->SetVertice(1, aP1);
- myPntArray->SetVertice(2, aP2);
+ myPntArray = new Graphic3d_ArrayOfPoints(2, withColor);
+ myPntArray->AddVertex(aP1);
+ myPntArray->AddVertex(aP2);
return true;
}
/// Update myPntArray according to presentation positions
/// \return true in case of success
- virtual bool updateIfReadyToDisplay(double theStep) const;
+ virtual bool updateIfReadyToDisplay(double theStep, bool withColor) const;
};
#endif
\ No newline at end of file
const std::shared_ptr<GeomAPI_Ax3>& thePlane)
: SketcherPrs_SymbolPrs(theConstraint, thePlane)
{
- myPntArray = new Graphic3d_ArrayOfPoints(2);
- myPntArray->AddVertex(0., 0., 0.);
- myPntArray->AddVertex(0., 0., 0.);
}
bool SketcherPrs_Equal::IsReadyToDisplay(ModelAPI_Feature* theConstraint,
return aReadyToDisplay;
}
-bool SketcherPrs_Equal::updateIfReadyToDisplay(double theStep) const
+bool SketcherPrs_Equal::updateIfReadyToDisplay(double theStep, bool withColor) const
{
if (!IsReadyToDisplay(myConstraint, myPlane))
return false;
SketcherPrs_PositionMgr* aMgr = SketcherPrs_PositionMgr::get();
gp_Pnt aP1 = aMgr->getPosition(aObj1, this, theStep);
gp_Pnt aP2 = aMgr->getPosition(aObj2, this, theStep);
- myPntArray->SetVertice(1, aP1);
- myPntArray->SetVertice(2, aP2);
+
+ myPntArray = new Graphic3d_ArrayOfPoints(2, withColor);
+ myPntArray->AddVertex(aP1);
+ myPntArray->AddVertex(aP2);
return true;
}
/// Update myPntArray according to presentation positions
/// \return true in case of success
- virtual bool updateIfReadyToDisplay(double theStep) const;
+ virtual bool updateIfReadyToDisplay(double theStep, bool withColor) const;
};
#endif
\ No newline at end of file
return aReadyToDisplay;
}
-bool SketcherPrs_HVDirection::updateIfReadyToDisplay(double theStep) const
+bool SketcherPrs_HVDirection::updateIfReadyToDisplay(double theStep, bool withColor) const
{
if (!IsReadyToDisplay(myConstraint, myPlane))
return false;
ObjectPtr aObj = SketcherPrs_Tools::getResult(myConstraint, SketchPlugin_Constraint::ENTITY_A());
SketcherPrs_PositionMgr* aMgr = SketcherPrs_PositionMgr::get();
gp_Pnt aP1 = aMgr->getPosition(aObj, this, theStep);
- myPntArray->SetVertice(1, aP1);
+ myPntArray = new Graphic3d_ArrayOfPoints(1, withColor);
+ myPntArray->AddVertex(aP1);
return true;
}
/// Update myPntArray according to presentation positions
/// \return true in case of success
- virtual bool updateIfReadyToDisplay(double theStep) const;
+ virtual bool updateIfReadyToDisplay(double theStep, bool withColor) const;
private:
bool myIsHorisontal;
return aReadyToDisplay;
}
-bool SketcherPrs_Middle::updateIfReadyToDisplay(double theStep) const
+bool SketcherPrs_Middle::updateIfReadyToDisplay(double theStep, bool withColor) const
{
if (!IsReadyToDisplay(myConstraint, myPlane))
return false;
ObjectPtr aPointObject;
// find a line result to set middle symbol near it
+ myPntArray = new Graphic3d_ArrayOfPoints(1, withColor);
AttributePtr anAttribute =
SketcherPrs_Tools::getAttribute(myConstraint, SketchPlugin_Constraint::ENTITY_A());
if (!anAttribute.get()) {
/// Update myPntArray according to presentation positions
/// \return true in case of success
- virtual bool updateIfReadyToDisplay(double theStep) const;
+ virtual bool updateIfReadyToDisplay(double theStep, bool withColor) const;
/// Draw shape of the object. Find shape result if the object is feature
void drawLine(const Handle(Prs3d_Presentation)& thePrs, Quantity_Color theColor,
return aReadyToDisplay;
}
-bool SketcherPrs_Mirror::updateIfReadyToDisplay(double theStep) const
+bool SketcherPrs_Mirror::updateIfReadyToDisplay(double theStep, bool withColor) const
{
if (!IsReadyToDisplay(myConstraint, myPlane))
return false;
SketcherPrs_PositionMgr* aMgr = SketcherPrs_PositionMgr::get();
int aNb = anAttrB->size();
- myPntArray = new Graphic3d_ArrayOfPoints(2 * aNb);
+ myPntArray = new Graphic3d_ArrayOfPoints(2 * aNb, withColor);
int i;
ObjectPtr aObj;
gp_Pnt aP1;
/// Update myPntArray according to presentation positions
/// \return true in case of success
- virtual bool updateIfReadyToDisplay(double theStep) const;
+ virtual bool updateIfReadyToDisplay(double theStep, bool withColor) const;
};
#endif
\ No newline at end of file
const std::shared_ptr<GeomAPI_Ax3>& thePlane)
: SketcherPrs_SymbolPrs(theConstraint, thePlane)
{
- // Create default array
- myPntArray = new Graphic3d_ArrayOfPoints(2);
- myPntArray->AddVertex(0., 0., 0.);
- myPntArray->AddVertex(0., 0., 0.);
}
bool SketcherPrs_Parallel::IsReadyToDisplay(ModelAPI_Feature* theConstraint,
return aReadyToDisplay;
}
-bool SketcherPrs_Parallel::updateIfReadyToDisplay(double theStep) const
+bool SketcherPrs_Parallel::updateIfReadyToDisplay(double theStep, bool withColor) const
{
if (!IsReadyToDisplay(myConstraint, myPlane))
return false;
SketcherPrs_PositionMgr* aMgr = SketcherPrs_PositionMgr::get();
gp_Pnt aP1 = aMgr->getPosition(aObj1, this, theStep);
gp_Pnt aP2 = aMgr->getPosition(aObj2, this, theStep);
- myPntArray->SetVertice(1, aP1);
- myPntArray->SetVertice(2, aP2);
+ myPntArray = new Graphic3d_ArrayOfPoints(2, withColor);
+ myPntArray->AddVertex(aP1);
+ myPntArray->AddVertex(aP2);
return true;
}
/// Update myPntArray according to presentation positions
/// \return true in case of success
- virtual bool updateIfReadyToDisplay(double theStep) const;
+ virtual bool updateIfReadyToDisplay(double theStep, bool withColor) const;
};
#endif
\ No newline at end of file
const std::shared_ptr<GeomAPI_Ax3>& thePlane)
: SketcherPrs_SymbolPrs(theConstraint, thePlane)
{
- // Create default array
- myPntArray = new Graphic3d_ArrayOfPoints(2);
- myPntArray->AddVertex(0., 0., 0.);
- myPntArray->AddVertex(0., 0., 0.);
}
bool SketcherPrs_Perpendicular::IsReadyToDisplay(ModelAPI_Feature* theConstraint,
return aReadyToDisplay;
}
-bool SketcherPrs_Perpendicular::updateIfReadyToDisplay(double theStep) const
+bool SketcherPrs_Perpendicular::updateIfReadyToDisplay(double theStep, bool withColor) const
{
if (!IsReadyToDisplay(myConstraint, myPlane))
return false;
SketcherPrs_PositionMgr* aMgr = SketcherPrs_PositionMgr::get();
gp_Pnt aP1 = aMgr->getPosition(aObj1, this, theStep);
gp_Pnt aP2 = aMgr->getPosition(aObj2, this, theStep);
- myPntArray->SetVertice(1, aP1);
- myPntArray->SetVertice(2, aP2);
+ myPntArray = new Graphic3d_ArrayOfPoints(2, withColor);
+ myPntArray->AddVertex(aP1);
+ myPntArray->AddVertex(aP2);
return true;
}
/// Update myPntArray according to presentation positions
/// \return true in case of success
- virtual bool updateIfReadyToDisplay(double theStep) const;
+ virtual bool updateIfReadyToDisplay(double theStep, bool withColor) const;
};
#endif
\ No newline at end of file
return aReadyToDisplay;
}
-bool SketcherPrs_Rigid::updateIfReadyToDisplay(double theStep) const
+bool SketcherPrs_Rigid::updateIfReadyToDisplay(double theStep, bool withColor) const
{
if (!IsReadyToDisplay(myConstraint, myPlane))
return false;
+ myPntArray = new Graphic3d_ArrayOfPoints(1, withColor);
std::shared_ptr<ModelAPI_Data> aData = myConstraint->data();
std::shared_ptr<ModelAPI_AttributeRefAttr> anAttr =
aData->refattr(SketchPlugin_Constraint::ENTITY_A());
SketcherPrs_PositionMgr* aMgr = SketcherPrs_PositionMgr::get();
gp_Pnt aP1 = aMgr->getPosition(aObj, this, theStep);
- myPntArray->SetVertice(1, aP1);
+ myPntArray->AddVertex(aP1);
} else {
// The constraint attached to a point
std::shared_ptr<GeomAPI_Pnt2d> aPnt = SketcherPrs_Tools::getPoint(myConstraint,
SketchPlugin_Constraint::ENTITY_A());
std::shared_ptr<GeomAPI_Pnt> aPoint = myPlane->to3D(aPnt->x(), aPnt->y() + theStep);
- myPntArray->SetVertice(1, aPoint->impl<gp_Pnt>());
+ myPntArray->AddVertex(aPoint->impl<gp_Pnt>());
}
return true;
}
/// Update myPntArray according to presentation positions
/// \return true in case of success
- virtual bool updateIfReadyToDisplay(double theStep) const;
+ virtual bool updateIfReadyToDisplay(double theStep, bool withColor) const;
};
Handle(OpenGl_View) aView = theWorkspace->View();
double aScale = aView->Camera()->Scale();
// Update points coordinate taking the viewer scale into account
- myObj->updateIfReadyToDisplay(MyDist * aScale);
+ myObj->updateIfReadyToDisplay(MyDist * aScale, myObj->myIsCustomColor);
if (myIsVboInit) {
if (myVboAttribs) {
const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
SketcherPrs_SymbolPrs::SketcherPrs_SymbolPrs(ModelAPI_Feature* theConstraint,
const std::shared_ptr<GeomAPI_Ax3>& thePlane)
- : AIS_InteractiveObject(), myConstraint(theConstraint), myPlane(thePlane), myIsConflicting(false)
+ : AIS_InteractiveObject(), myConstraint(theConstraint), myPlane(thePlane), myIsCustomColor(false)
{
SetAutoHilight(Standard_False);
- myPntArray = new Graphic3d_ArrayOfPoints(1);
- myPntArray->AddVertex(0., 0., 0.);
}
//*********************************************************************************
myAspect = new Graphic3d_AspectMarker3d();
else
myAspect = new Graphic3d_AspectMarker3d(aIcon);
+
+ myAspect->SetColor(myCustomColor);
}
}
// it updates array of points if the presentation is ready to display, or the array of points
// contains the previous values
- bool aReadyToDisplay = updateIfReadyToDisplay(20);
+ bool aReadyToDisplay = updateIfReadyToDisplay(20, myIsCustomColor);
int aNbVertex = myPntArray->VertexNumber();
if (myOwner.IsNull()) {
for (int i = 1; i <= aNbVertex; i++) {
Handle(SketcherPrs_SensitivePoint) aSP = new SketcherPrs_SensitivePoint(myOwner, i);
mySPoints.Append(aSP);
+ if (myIsCustomColor)
+ myPntArray->SetVertexColor(i, myCustomColor);
}
- Handle(OpenGl_Group) aGroup = Handle(OpenGl_Group)::DownCast(thePresentation->NewGroup());
+ Handle(OpenGl_Group) aGroup =
+ Handle(OpenGl_Group)::DownCast(Prs3d_Root::CurrentGroup (thePresentation));
aGroup->SetPrimitivesAspect(myAspect);
// Recompute boundary box of the group
}
//*********************************************************************************
-void SketcherPrs_SymbolPrs::SetConflictingConstraint(const bool& theConflicting,
- const std::vector<int>& theColor)
+void SketcherPrs_SymbolPrs::SetCustomColor(const std::vector<int>& theColor)
{
- if (theConflicting)
- {
- if (!myAspect.IsNull())
- myAspect->SetColor (Quantity_Color (theColor[0] / 255., theColor[1] / 255.,
- theColor[2] / 255., Quantity_TOC_RGB));
- myIsConflicting = true;
- }
+ myIsCustomColor = !theColor.empty();
+ if (myIsCustomColor)
+ myCustomColor = Quantity_Color(theColor[0] / 255., theColor[1] / 255.,
+ theColor[2] / 255., Quantity_TOC_RGB);
else
- {
- if (!myAspect.IsNull())
- myAspect->SetColor (Quantity_Color (1.0, 1.0, 0.0, Quantity_TOC_RGB));
- myIsConflicting = false;
- }
+ myCustomColor = Quantity_Color (1.0, 1.0, 0.0, Quantity_TOC_RGB);
+
+ if (!myAspect.IsNull())
+ myAspect->SetColor (myCustomColor);
}
//*********************************************************************************
/// Set state of the presentation, in case of conflicting state, the icon of the presentation is
/// visualized in error color. The state is stored in an internal field, so should be changed
/// when constraint become not conflicting
- /// \param theConflicting a state
/// \param theColor a color for conflicting object
- Standard_EXPORT void SetConflictingConstraint(const bool& theConflicting,
- const std::vector<int>& theColor);
+ Standard_EXPORT void SetCustomColor(const std::vector<int>& theColor);
/// Add a bounding box of the presentation to common bounding box
/// \param theBndBox the common bounding box to update
/// Update myPntArray according to presentation positions
/// \return true in case of success
- virtual bool updateIfReadyToDisplay(double theStep) const { return true; }
+ virtual bool updateIfReadyToDisplay(double theStep, bool withColor) const { return true; }
/// Draw a shape into the given presentation scene
/// \param theShape the shape to draw
Select3D_EntitySequence mySPoints;
- bool myIsConflicting; /// state if the presentation is visualized in error state
+ bool myIsCustomColor; /// state if the presentation is visualized in custom color
+ Quantity_Color myCustomColor; /// the color of mid ring if there is a conflict
+
+ //bool myIsConflicting; /// state if the presentation is visualized in error state
Handle(Image_AlienPixMap) myErrorIcon;
Handle(Graphic3d_MarkerImage) myErrorImage;
const std::shared_ptr<GeomAPI_Ax3>& thePlane)
: SketcherPrs_SymbolPrs(theConstraint, thePlane)
{
- // Init default points
- myPntArray = new Graphic3d_ArrayOfPoints(2);
- myPntArray->AddVertex(0., 0., 0.);
- myPntArray->AddVertex(0., 0., 0.);
}
bool SketcherPrs_Tangent::IsReadyToDisplay(ModelAPI_Feature* theConstraint,
return aReadyToDisplay;
}
-bool SketcherPrs_Tangent::updateIfReadyToDisplay(double theStep) const
+bool SketcherPrs_Tangent::updateIfReadyToDisplay(double theStep, bool withColor) const
{
if (!IsReadyToDisplay(myConstraint, myPlane))
return false;
SketcherPrs_PositionMgr* aMgr = SketcherPrs_PositionMgr::get();
gp_Pnt aP1 = aMgr->getPosition(aObj1, this, theStep);
gp_Pnt aP2 = aMgr->getPosition(aObj2, this, theStep);
- myPntArray->SetVertice(1, aP1);
- myPntArray->SetVertice(2, aP2);
+ myPntArray = new Graphic3d_ArrayOfPoints(2, withColor);
+ myPntArray->AddVertex(aP1);
+ myPntArray->AddVertex(aP2);
return true;
}
/// Update myPntArray according to presentation positions
/// \return true in case of success
- virtual bool updateIfReadyToDisplay(double theStep) const;
+ virtual bool updateIfReadyToDisplay(double theStep, bool withColor) const;
};
#endif
\ No newline at end of file
return aReadyToDisplay;
}
-bool SketcherPrs_Transformation::updateIfReadyToDisplay(double theStep) const
+bool SketcherPrs_Transformation::updateIfReadyToDisplay(double theStep, bool withColor) const
{
if (!IsReadyToDisplay(myConstraint, myPlane))
return false;
}
SketcherPrs_PositionMgr* aMgr = SketcherPrs_PositionMgr::get();
- myPntArray = new Graphic3d_ArrayOfPoints(aNbB);
+ myPntArray = new Graphic3d_ArrayOfPoints(aNbB, withColor);
int i;
ObjectPtr aObj;
/// Update myPntArray according to presentation positions
/// \return true in case of success
- virtual bool updateIfReadyToDisplay(double theStep) const;
+ virtual bool updateIfReadyToDisplay(double theStep, bool withColor) const;
private:
bool myIsTranslation;
}
bool isCustomized = aCustomPrs.get() &&
aCustomPrs->customisePresentation(aResult, anAISObj, myCustomPrs);
+ isCustomized = myWorkshop->module()->afterCustomisePresentation(aResult, anAISObj, myCustomPrs)
+ || isCustomized;
return isCustomized;
}
/// Update actions for the given feature
/// \param theFeature a feature
- void updateActions(const FeaturePtr& theFeature);
+ virtual void updateActions(const FeaturePtr& theFeature);
/// Update enable state of AcceptAll action if the feature uses it
/// \param theFeature a feature
#include "XGUI_Displayer.h"
#include "XGUI_PropertyPanel.h"
#include "XGUI_ActionsMgr.h"
+#include "XGUI_ErrorMgr.h"
#include <ModuleBase_IModule.h>
#include <ModuleBase_ViewerPrs.h>
return myWorkshop->propertyPanel();
}
+ModuleBase_IErrorMgr* XGUI_ModuleConnector::errorMgr() const
+{
+ return myWorkshop->errorMgr();
+}
+
ModuleBase_Operation* XGUI_ModuleConnector::currentOperation() const
{
return myWorkshop->operationMgr()->currentOperation();
//! Returns property panel
virtual ModuleBase_IPropertyPanel* propertyPanel() const;
+ //! Returns error manager
+ virtual ModuleBase_IErrorMgr* errorMgr() const;
+
//! Returns currently active operation
virtual ModuleBase_Operation* currentOperation() const;
"""
-Test case for Primitive Cylinder feature.
+Test case for Primitive Cylinder feature.
Written on High API.
"""
#from ModelAPI import *
SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchLine_3.endPoint())
+model.do()
# Extrusion
Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_1f-SketchLine_2f-SketchLine_3f")], model.selection(), 100, 0)
Cylinder_9 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "InvalidName"), 5, 10)
Cylinder_10 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "Sketch_1/Vertex-SketchLine_3s-SketchLine_2e"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_3"), 50, 120)
Cylinder_11 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "Vertex_1_1"), model.selection("EDGE", "Edge_1_1"), 60, 100)
-Cylinder_12 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "Extrusion_1_1/Generated_Face_5&Extrusion_1_1/Generated_Face_1&Extrusion_1_1/To_Face_1"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_3&Extrusion_1_1/To_Face_1"), 5, 10)
+Cylinder_12 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "Extrusion_1_1/Generated_Face_3&Extrusion_1_1/Generated_Face_1&Extrusion_1_1/To_Face_1"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_3&Extrusion_1_1/To_Face_1"), 5, 10)
Cylinder_13 = model.addCylinder(Part_1_doc, "r", "h")
Cylinder_14 = model.addCylinder(Part_1_doc, 5, 10, 45)
Cylinder_15 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "Point_1"), model.selection("EDGE", "PartSet/OX"), 5, 10, 90)
Cylinder_26 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "InvalidName"), 5, 10, 90)
Cylinder_27 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "Sketch_1/Vertex-SketchLine_2s-SketchLine_1e"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_3"), 50, 120, 90)
Cylinder_28 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "Vertex_1_1"), model.selection("EDGE", "Edge_2_1"), 60, 100, 180)
-Cylinder_29 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "Extrusion_2_1/Generated_Face_5&Extrusion_1_1/Generated_Face_4&Extrusion_1_1/To_Face_1"), model.selection("EDGE", "Extrusion_2_1/Generated_Face_2&Extrusion_2_1/To_Face_1"), 5, 10, 120)
+Cylinder_29 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "Extrusion_2_1/Generated_Face_3&Extrusion_2_1/Generated_Face_2&Extrusion_2_1/To_Face_1"), model.selection("EDGE", "Extrusion_2_1/Generated_Face_2&Extrusion_2_1/To_Face_1"), 5, 10, 120)
Cylinder_30 = model.addCylinder(Part_1_doc, "r2", "h2", "angle")
model.do()
SketchLine_33.result().setName("SketchLine_32")
SketchConstraintDistance_10 = Sketch_4.setDistance(SketchLine_22.startPoint(), SketchLine_32.result(), 4.5)
SketchConstraintDistance_10.setName("SketchConstraintDistance_13")
-SketchPoint_2 = Sketch_4.addPoint(0.0367430766441097, 12.3548825983447)
SketchLine_34 = Sketch_4.addLine(-8.5, 12.23281708580693, 8.5, 12.23281708580693)
SketchLine_34.setName("SketchLine_33")
SketchLine_34.result().setName("SketchLine_33")
SketchConstraintDistance_17.setName("SketchConstraintDistance_18")
SketchConstraintDistance_18 = Sketch_4.setDistance(SketchLine_30.endPoint(), SketchLine_20.result(), 6.1)
SketchConstraintDistance_18.setName("SketchConstraintDistance_19")
+SketchConstraintCoincidence_67 = Sketch_4.setCoincident(SketchArc_3.center(), SketchCircle_3.center())
+SketchConstraintCoincidence_67.setName("SketchConstraintCoincidence_149")
+SketchConstraintCoincidence_68 = Sketch_4.setCoincident(SketchArc_4.center(), SketchArc_3.center())
+SketchConstraintCoincidence_68.setName("SketchConstraintCoincidence_150")
+SketchConstraintDistance_19 = Sketch_4.setDistance(SketchArc_4.center(), SketchLine_34.result(), 12)
+SketchConstraintDistance_19.setName("SketchConstraintDistance_43")
model.do()
Extrusion_3 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_4")], model.selection(), 50, 30)
Extrusion_4 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_3")], model.selection(), 22, 22)
model.testNbResults(Boolean_7, 1)
model.testNbSubResults(Boolean_7, [0])
model.testNbSubShapes(Boolean_7, GeomAPI_Shape.SOLID, [1])
-model.testNbSubShapes(Boolean_7, GeomAPI_Shape.FACE, [49])
-model.testNbSubShapes(Boolean_7, GeomAPI_Shape.EDGE, [263])
-model.testNbSubShapes(Boolean_7, GeomAPI_Shape.VERTEX, [526])
-model.testResultsVolumes(Boolean_7, [157000.328896829247241839766502380])
+model.testNbSubShapes(Boolean_7, GeomAPI_Shape.FACE, [50])
+model.testNbSubShapes(Boolean_7, GeomAPI_Shape.EDGE, [266])
+model.testNbSubShapes(Boolean_7, GeomAPI_Shape.VERTEX, [532])
+model.testResultsVolumes(Boolean_7, [156999.218330596777377650141716003])
assert(model.checkPythonDump)
model.begin()
partSet = model.moduleDocument()
Part_1 = model.addPart(partSet)
+Part_1.result().setColor(255, 85, 0)
Part_1_doc = Part_1.document()
Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
SketchLine_1 = Sketch_1.addLine(0, 0, 60, 0)
SketchLine_21.setName("SketchLine_23")
SketchLine_21.result().setName("SketchLine_23")
SketchLine_21.setAuxiliary(True)
-SketchLine_22 = Sketch_3.addLine(model.selection("EDGE", "Extrusion_1_1/Generated_Face_4&Extrusion_1_1/Generated_Face_5"))
+SketchLine_22 = Sketch_3.addLine(model.selection("EDGE", "Extrusion_1_1/Generated_Face_5&Extrusion_1_1/Generated_Face_4"))
SketchLine_22.setName("SketchLine_24")
SketchLine_22.result().setName("SketchLine_24")
SketchConstraintCoincidence_27 = Sketch_3.setCoincident(SketchLine_21.startPoint(), SketchLine_22.result())
SketchConstraintCoincidence_49.setName("SketchConstraintCoincidence_53")
SketchConstraintCoincidence_50 = Sketch_3.setCoincident(SketchLine_33.endPoint(), SketchLine_34.endPoint())
SketchConstraintCoincidence_50.setName("SketchConstraintCoincidence_54")
-SketchPoint_4 = Sketch_3.addPoint(16.50014787857639, -6)
+SketchPoint_4 = Sketch_3.addPoint(16.50014787857639, -5.999999999999999)
SketchPoint_4.setAuxiliary(True)
SketchConstraintCoincidence_51 = Sketch_3.setCoincident(SketchPoint_4.coordinates(), SketchLine_34.result())
SketchConstraintCoincidence_51.setName("SketchConstraintCoincidence_55")
SketchLine_46.result().setName("SketchLine_49")
SketchLine_45.setName("SketchLine_48")
SketchLine_45.result().setName("SketchLine_48")
+SketchLine_44.setName("SketchLine_46")
+SketchLine_44.result().setName("SketchLine_46")
SketchLine_43.setName("SketchLine_47")
SketchLine_43.result().setName("SketchLine_47")
SketchLine_42.setName("SketchLine_46")
model.do()
ExtrusionFuse_1 = model.addExtrusionFuse(Part_1_doc, [model.selection("COMPOUND", "Sketch_6")], model.selection(), model.selection("FACE", "Sketch_1/Face-SketchLine_1f-SketchLine_3f-SketchLine_4f-SketchLine_5f-SketchLine_7f-SketchArc_1_2f-SketchLine_8f-SketchLine_9f-SketchLine_10r-SketchLine_11r-SketchLine_12r-SketchLine_14r-SketchArc_2_2r"), 0, model.selection(), 0, [model.selection("SOLID", "ExtrusionCut_5_1")])
Sketch_7 = model.addSketch(Part_1_doc, model.selection("FACE", "ExtrusionCut_2_1/Modfied_12"))
-SketchLine_64 = Sketch_7.addLine(50.25000013028279, -4.499999999999999, 31.24999999998802, -4.499999999999997)
+SketchLine_64 = Sketch_7.addLine(50.25000000000001, -4.5, 31.24999999998802, -4.499999999999997)
SketchLine_64.setName("SketchLine_76")
SketchLine_64.result().setName("SketchLine_76")
-SketchLine_65 = Sketch_7.addLine(51.00000000000001, -6.750000215087569, 51.00000000000001, -5.24999997149696)
+SketchLine_65 = Sketch_7.addLine(51.00000000000001, -6.749999999999998, 51.00000000000001, -5.24999997149696)
SketchLine_65.setName("SketchLine_78")
SketchLine_65.result().setName("SketchLine_78")
-SketchLine_66 = Sketch_7.addLine(31, -4.750000022881151, 31.00000000000001, -7.249995609843254)
+SketchLine_66 = Sketch_7.addLine(31, -4.750000022881151, 31, -7.249999999972618)
SketchLine_66.setName("SketchLine_80")
SketchLine_66.result().setName("SketchLine_80")
-SketchLine_67 = Sketch_7.addLine(31.25000370007456, -7.499999999999999, 50.24999994039248, -7.5)
+SketchLine_67 = Sketch_7.addLine(31.25000000003855, -7.5, 50.24999994039248, -7.5)
SketchLine_67.setName("SketchLine_79")
SketchLine_67.result().setName("SketchLine_79")
-SketchLine_69 = Sketch_7.addLine(51, -4.5, 31, -4.5)
-SketchLine_69.setName("SketchLine_66")
-SketchLine_69.result().setName("SketchLine_66")
-SketchLine_69.setAuxiliary(True)
-SketchLine_68 = Sketch_7.addLine(51, -7.5, 51, -4.5)
-SketchLine_68.setName("SketchLine_69")
-SketchLine_68.result().setName("SketchLine_69")
+SketchLine_68 = Sketch_7.addLine(51, -4.5, 31, -4.5)
+SketchLine_68.setName("SketchLine_66")
+SketchLine_68.result().setName("SketchLine_66")
SketchLine_68.setAuxiliary(True)
-SketchConstraintCoincidence_74 = Sketch_7.setCoincident(SketchLine_68.endPoint(), SketchLine_69.startPoint())
+SketchLine_69 = Sketch_7.addLine(51, -7.5, 51, -4.5)
+SketchLine_69.setAuxiliary(True)
+SketchConstraintCoincidence_74 = Sketch_7.setCoincident(SketchLine_69.endPoint(), SketchLine_68.startPoint())
SketchConstraintCoincidence_74.setName("SketchConstraintCoincidence_78")
SketchLine_70 = Sketch_7.addLine(31, -4.5, 31, -7.5)
SketchLine_70.setName("SketchLine_67")
SketchLine_70.result().setName("SketchLine_67")
SketchLine_70.setAuxiliary(True)
-SketchConstraintCoincidence_75 = Sketch_7.setCoincident(SketchLine_69.endPoint(), SketchLine_70.startPoint())
+SketchConstraintCoincidence_75 = Sketch_7.setCoincident(SketchLine_68.endPoint(), SketchLine_70.startPoint())
SketchConstraintCoincidence_75.setName("SketchConstraintCoincidence_79")
SketchLine_71 = Sketch_7.addLine(31, -7.5, 51, -7.5)
SketchLine_71.setName("SketchLine_68")
SketchLine_71.setAuxiliary(True)
SketchConstraintCoincidence_76 = Sketch_7.setCoincident(SketchLine_70.endPoint(), SketchLine_71.startPoint())
SketchConstraintCoincidence_76.setName("SketchConstraintCoincidence_80")
-SketchConstraintCoincidence_77 = Sketch_7.setCoincident(SketchLine_71.endPoint(), SketchLine_68.startPoint())
+SketchConstraintCoincidence_77 = Sketch_7.setCoincident(SketchLine_71.endPoint(), SketchLine_69.startPoint())
SketchConstraintCoincidence_77.setName("SketchConstraintCoincidence_81")
-SketchConstraintHorizontal_12 = Sketch_7.setHorizontal(SketchLine_69.result())
+SketchConstraintHorizontal_12 = Sketch_7.setHorizontal(SketchLine_68.result())
SketchConstraintHorizontal_12.setName("SketchConstraintHorizontal_13")
SketchConstraintVertical_12 = Sketch_7.setVertical(SketchLine_70.result())
SketchConstraintHorizontal_13 = Sketch_7.setHorizontal(SketchLine_71.result())
SketchConstraintHorizontal_13.setName("SketchConstraintHorizontal_14")
-SketchConstraintVertical_13 = Sketch_7.setVertical(SketchLine_68.result())
+SketchConstraintVertical_13 = Sketch_7.setVertical(SketchLine_69.result())
SketchLine_72 = Sketch_7.addLine(31, -7.5, 51, -4.5)
SketchLine_72.setName("SketchLine_70")
SketchLine_72.result().setName("SketchLine_70")
SketchConstraintCoincidence_79 = Sketch_7.setCoincident(SketchLine_71.startPoint(), SketchLine_72.startPoint())
SketchConstraintCoincidence_79.setName("SketchConstraintCoincidence_83")
SketchPoint_8 = Sketch_7.addPoint(51, -4.5)
-SketchConstraintCoincidence_80 = Sketch_7.setCoincident(SketchLine_69.startPoint(), SketchPoint_8.coordinates())
+SketchConstraintCoincidence_80 = Sketch_7.setCoincident(SketchLine_68.startPoint(), SketchPoint_8.coordinates())
SketchConstraintCoincidence_80.setName("SketchConstraintCoincidence_84")
-SketchConstraintCoincidence_81 = Sketch_7.setCoincident(SketchLine_68.endPoint(), SketchPoint_8.coordinates())
+SketchConstraintCoincidence_81 = Sketch_7.setCoincident(SketchLine_69.endPoint(), SketchPoint_8.coordinates())
SketchConstraintCoincidence_81.setName("SketchConstraintCoincidence_85")
SketchPoint_9 = Sketch_7.addPoint(41, -6)
SketchPoint_9.setAuxiliary(True)
SketchConstraintCoincidence_82 = Sketch_7.setCoincident(SketchPoint_9.coordinates(), SketchLine_72.result())
SketchConstraintCoincidence_82.setName("SketchConstraintCoincidence_86")
SketchConstraintMiddle_3 = Sketch_7.setMiddlePoint(SketchLine_72.result(), SketchPoint_9.coordinates())
-SketchPoint_10 = Sketch_7.addPoint(21.00014787857639, -6)
+SketchPoint_10 = Sketch_7.addPoint(21.00014787857639, -5.999999999999999)
SketchPoint_10.setAuxiliary(True)
SketchLine_73 = Sketch_7.addLine(21.00014787857639, -10.5, 21.00014787857639, -1.499999999999999)
SketchLine_73.setName("SketchLine_71")
SketchConstraintCoincidence_85.setName("SketchConstraintCoincidence_89")
SketchConstraintHorizontal_14 = Sketch_7.setHorizontal(SketchLine_74.result())
SketchConstraintHorizontal_14.setName("SketchConstraintHorizontal_15")
-SketchConstraintCoincidence_86 = Sketch_7.setCoincident(SketchLine_72.endPoint(), SketchLine_69.startPoint())
+SketchConstraintCoincidence_86 = Sketch_7.setCoincident(SketchLine_72.endPoint(), SketchLine_68.startPoint())
SketchConstraintCoincidence_86.setName("SketchConstraintCoincidence_90")
-SketchConstraintLength_12 = Sketch_7.setLength(SketchLine_68.result(), 3)
+SketchConstraintLength_12 = Sketch_7.setLength(SketchLine_69.result(), 3)
SketchConstraintLength_12.setName("SketchConstraintLength_13")
-SketchConstraintLength_13 = Sketch_7.setLength(SketchLine_69.result(), 20)
+SketchConstraintLength_13 = Sketch_7.setLength(SketchLine_68.result(), 20)
SketchConstraintLength_13.setName("SketchConstraintLength_14")
SketchPoint_11 = Sketch_7.addPoint(29, -10.5)
SketchConstraintDistance_13 = Sketch_7.setDistance(SketchPoint_11.coordinates(), SketchLine_70.result(), 2)
SketchConstraintRigid_6 = Sketch_7.setFixed(SketchPoint_11.result())
SketchConstraintRigid_6.setName("SketchConstraintRigid_15")
-SketchArc_14 = Sketch_7.addArc(50.24999999999999, -5.250000000000003, 51.00000000000001, -5.24999997149696, 50.25000013028279, -4.499999999999999, False)
+SketchArc_14 = Sketch_7.addArc(50.24999999999999, -5.250000000000003, 51.00000000000001, -5.24999997149696, 50.25000000000001, -4.5, False)
SketchLine_75 = Sketch_7.addLine(51, -7.5, 51.00000000000001, -5.24999997149696)
SketchLine_75.setName("SketchLine_74")
SketchLine_75.result().setName("SketchLine_74")
SketchLine_75.setAuxiliary(True)
SketchConstraintCoincidence_87 = Sketch_7.setCoincident(SketchArc_14.startPoint(), SketchLine_75.endPoint())
SketchConstraintCoincidence_87.setName("SketchConstraintCoincidence_91")
-SketchLine_76 = Sketch_7.addLine(50.25000013028279, -4.499999999999999, 31, -4.5)
+SketchLine_76 = Sketch_7.addLine(50.25000000000001, -4.5, 31, -4.5)
SketchLine_76.setName("SketchLine_73")
SketchLine_76.result().setName("SketchLine_73")
SketchLine_76.setAuxiliary(True)
SketchConstraintCoincidence_88.setName("SketchConstraintCoincidence_92")
SketchConstraintTangent_1 = Sketch_7.setTangent(SketchArc_14.results()[1], SketchLine_76.result())
SketchConstraintTangent_2 = Sketch_7.setTangent(SketchArc_14.results()[1], SketchLine_75.result())
-SketchConstraintCoincidence_89 = Sketch_7.setCoincident(SketchLine_69.endPoint(), SketchLine_76.endPoint())
+SketchConstraintCoincidence_89 = Sketch_7.setCoincident(SketchLine_68.endPoint(), SketchLine_76.endPoint())
SketchConstraintCoincidence_89.setName("SketchConstraintCoincidence_93")
-SketchConstraintCoincidence_90 = Sketch_7.setCoincident(SketchLine_68.startPoint(), SketchLine_75.startPoint())
+SketchConstraintCoincidence_90 = Sketch_7.setCoincident(SketchLine_69.startPoint(), SketchLine_75.startPoint())
SketchConstraintCoincidence_90.setName("SketchConstraintCoincidence_94")
-SketchConstraintCoincidence_91 = Sketch_7.setCoincident(SketchLine_76.startPoint(), SketchLine_69.result())
+SketchConstraintCoincidence_91 = Sketch_7.setCoincident(SketchLine_76.startPoint(), SketchLine_68.result())
SketchConstraintCoincidence_91.setName("SketchConstraintCoincidence_95")
-SketchConstraintCoincidence_92 = Sketch_7.setCoincident(SketchLine_75.endPoint(), SketchLine_68.result())
+SketchConstraintCoincidence_92 = Sketch_7.setCoincident(SketchLine_75.endPoint(), SketchLine_69.result())
SketchConstraintCoincidence_92.setName("SketchConstraintCoincidence_96")
SketchArc_15 = Sketch_7.addArc(31.25000000000067, -4.750000000000669, 31.24999999998802, -4.499999999999997, 31, -4.750000022881151, False)
SketchConstraintCoincidence_93 = Sketch_7.setCoincident(SketchArc_15.startPoint(), SketchLine_64.endPoint())
SketchConstraintCoincidence_97.setName("SketchConstraintCoincidence_101")
SketchConstraintCoincidence_98 = Sketch_7.setCoincident(SketchLine_64.endPoint(), SketchLine_76.result())
SketchConstraintCoincidence_98.setName("SketchConstraintCoincidence_102")
-SketchArc_16 = Sketch_7.addArc(50.25, -6.749999999999999, 50.24999994039248, -7.5, 51.00000000000001, -6.750000215087569, False)
+SketchArc_16 = Sketch_7.addArc(50.25, -6.749999999999999, 50.24999994039248, -7.5, 51.00000000000001, -6.749999999999998, False)
SketchLine_78 = Sketch_7.addLine(31, -7.5, 50.24999994039248, -7.5)
SketchLine_78.setName("SketchLine_77")
SketchLine_78.result().setName("SketchLine_77")
SketchConstraintCoincidence_103.setName("SketchConstraintCoincidence_107")
SketchConstraintCoincidence_104 = Sketch_7.setCoincident(SketchLine_65.startPoint(), SketchLine_75.result())
SketchConstraintCoincidence_104.setName("SketchConstraintCoincidence_108")
-SketchArc_17 = Sketch_7.addArc(31.25000000000003, -7.250000000000001, 31.00000000000001, -7.249995609843254, 31.25000370007456, -7.499999999999999, False)
+SketchArc_17 = Sketch_7.addArc(31.25000000000003, -7.250000000000001, 31, -7.249999999972618, 31.25000000003855, -7.5, False)
SketchConstraintCoincidence_105 = Sketch_7.setCoincident(SketchArc_17.startPoint(), SketchLine_66.endPoint())
SketchConstraintCoincidence_105.setName("SketchConstraintCoincidence_109")
SketchConstraintCoincidence_106 = Sketch_7.setCoincident(SketchArc_17.endPoint(), SketchLine_67.startPoint())
model.do()
ExtrusionCut_9 = model.addExtrusionCut(Part_1_doc, [model.selection("WIRE", "Sketch_10/Wire-SketchCircle_1_2f")], model.selection(), 0, 0.75, [model.selection("SOLID", "ExtrusionCut_8_1")])
model.do()
+Part_2 = model.addPart(partSet)
+Part_2_doc = Part_2.document()
+Sketch_11 = model.addSketch(Part_2_doc, model.defaultPlane("XOY"))
+SketchLine_107 = Sketch_11.addLine(0, 0, 60, 0)
+SketchPoint_25 = Sketch_11.addPoint(model.selection("VERTEX", "PartSet/Origin"))
+SketchConstraintCoincidence_174 = Sketch_11.setCoincident(SketchLine_107.startPoint(), SketchPoint_25.result())
+SketchLine_108 = Sketch_11.addLine(60, 0, 60, 1.5)
+SketchLine_108.setName("SketchLine_3")
+SketchLine_108.result().setName("SketchLine_3")
+SketchConstraintCoincidence_175 = Sketch_11.setCoincident(SketchLine_107.endPoint(), SketchLine_108.startPoint())
+SketchConstraintCoincidence_175.setName("SketchConstraintCoincidence_3")
+SketchLine_109 = Sketch_11.addLine(60, 1.5, 57, 1.5)
+SketchLine_109.setName("SketchLine_4")
+SketchLine_109.result().setName("SketchLine_4")
+SketchConstraintCoincidence_176 = Sketch_11.setCoincident(SketchLine_108.endPoint(), SketchLine_109.startPoint())
+SketchConstraintCoincidence_176.setName("SketchConstraintCoincidence_4")
+SketchLine_110 = Sketch_11.addLine(57, 1.5, 29, 7.5)
+SketchLine_110.setName("SketchLine_5")
+SketchLine_110.result().setName("SketchLine_5")
+SketchConstraintCoincidence_177 = Sketch_11.setCoincident(SketchLine_109.endPoint(), SketchLine_110.startPoint())
+SketchConstraintCoincidence_177.setName("SketchConstraintCoincidence_5")
+SketchLine_111 = Sketch_11.addLine(28, 7.5, 28, 8)
+SketchLine_111.setName("SketchLine_7")
+SketchLine_111.result().setName("SketchLine_7")
+SketchArc_24 = Sketch_11.addArc(25.00007393928819, 7.9789374678129, 28, 8, 22.00014787857639, 8, False)
+SketchLine_112 = Sketch_11.addLine(22.00014787857639, 8, 22.00014787857639, 7.5)
+SketchLine_112.setName("SketchLine_8")
+SketchLine_112.result().setName("SketchLine_8")
+SketchConstraintCoincidence_178 = Sketch_11.setCoincident(SketchArc_24.endPoint(), SketchLine_112.startPoint())
+SketchConstraintCoincidence_178.setName("SketchConstraintCoincidence_8")
+SketchLine_113 = Sketch_11.addLine(22.00014787857639, 7.5, 21.00014787857639, 7.5)
+SketchLine_113.setName("SketchLine_9")
+SketchLine_113.result().setName("SketchLine_9")
+SketchConstraintCoincidence_179 = Sketch_11.setCoincident(SketchLine_112.endPoint(), SketchLine_113.startPoint())
+SketchConstraintCoincidence_179.setName("SketchConstraintCoincidence_9")
+SketchLine_114 = Sketch_11.addLine(0, 0, 0, 3.499999999999999)
+SketchLine_114.setName("SketchLine_10")
+SketchLine_114.result().setName("SketchLine_10")
+SketchConstraintCoincidence_180 = Sketch_11.setCoincident(SketchLine_107.startPoint(), SketchLine_114.startPoint())
+SketchConstraintCoincidence_180.setName("SketchConstraintCoincidence_10")
+SketchConstraintCoincidence_181 = Sketch_11.setCoincident(SketchPoint_25.coordinates(), SketchLine_114.startPoint())
+SketchConstraintCoincidence_181.setName("SketchConstraintCoincidence_11")
+SketchLine_115 = Sketch_11.addLine(0, 3.499999999999999, 8, 5)
+SketchLine_115.setName("SketchLine_11")
+SketchLine_115.result().setName("SketchLine_11")
+SketchConstraintCoincidence_182 = Sketch_11.setCoincident(SketchLine_114.endPoint(), SketchLine_115.startPoint())
+SketchConstraintCoincidence_182.setName("SketchConstraintCoincidence_13")
+SketchLine_116 = Sketch_11.addLine(8, 5, 10.426976887961, 4.40018070612629)
+SketchLine_116.setName("SketchLine_12")
+SketchLine_116.result().setName("SketchLine_12")
+SketchConstraintCoincidence_183 = Sketch_11.setCoincident(SketchLine_115.endPoint(), SketchLine_116.startPoint())
+SketchConstraintCoincidence_183.setName("SketchConstraintCoincidence_14")
+SketchConstraintLength_18 = Sketch_11.setLength(SketchLine_107.result(), 60)
+SketchConstraintHorizontal_23 = Sketch_11.setHorizontal(SketchLine_107.result())
+SketchConstraintVertical_20 = Sketch_11.setVertical(SketchLine_108.result())
+SketchConstraintHorizontal_24 = Sketch_11.setHorizontal(SketchLine_109.result())
+SketchConstraintHorizontal_25 = Sketch_11.setHorizontal(SketchLine_113.result())
+SketchConstraintHorizontal_25.setName("SketchConstraintHorizontal_4")
+SketchConstraintVertical_21 = Sketch_11.setVertical(SketchLine_111.result())
+SketchConstraintVertical_22 = Sketch_11.setVertical(SketchLine_112.result())
+SketchConstraintCoincidence_184 = Sketch_11.setCoincident(SketchLine_111.endPoint(), SketchArc_24.startPoint())
+SketchConstraintCoincidence_184.setName("SketchConstraintCoincidence_15")
+SketchConstraintVertical_23 = Sketch_11.setVertical(SketchLine_114.result())
+SketchConstraintDistance_18 = Sketch_11.setDistance(SketchLine_114.endPoint(), SketchLine_107.result(), 3.5)
+SketchConstraintDistance_19 = Sketch_11.setDistance(SketchLine_115.endPoint(), SketchLine_114.result(), 8)
+SketchConstraintLength_19 = Sketch_11.setLength(SketchLine_116.result(), 2.5)
+SketchConstraintRadius_12 = Sketch_11.setRadius(SketchArc_24.results()[1], 3)
+SketchConstraintLength_20 = Sketch_11.setLength(SketchLine_112.result(), 0.5)
+SketchConstraintLength_21 = Sketch_11.setLength(SketchLine_113.result(), 1)
+SketchConstraintLength_22 = Sketch_11.setLength(SketchLine_111.result(), 0.5)
+SketchConstraintDistance_20 = Sketch_11.setDistance(SketchLine_112.endPoint(), SketchLine_107.result(), 7.5)
+SketchConstraintLength_23 = Sketch_11.setLength(SketchLine_109.result(), 3)
+SketchConstraintLength_23.setName("SketchConstraintLength_7")
+SketchConstraintLength_24 = Sketch_11.setLength(SketchLine_108.result(), 1.5)
+SketchConstraintLength_24.setName("SketchConstraintLength_8")
+SketchConstraintDistance_21 = Sketch_11.setDistance(SketchLine_115.endPoint(), SketchLine_107.result(), 5)
+SketchConstraintDistance_22 = Sketch_11.setDistance(SketchLine_111.startPoint(), SketchLine_107.result(), 7.5)
+SketchLine_117 = Sketch_11.addLine(12.81710695710752, 0, 12.81710695710752, 7.765286531476907)
+SketchLine_117.setName("SketchLine_13")
+SketchLine_117.result().setName("SketchLine_13")
+SketchLine_117.setAuxiliary(True)
+SketchConstraintCoincidence_185 = Sketch_11.setCoincident(SketchLine_117.startPoint(), SketchLine_107.result())
+SketchConstraintCoincidence_185.setName("SketchConstraintCoincidence_16")
+SketchConstraintVertical_24 = Sketch_11.setVertical(SketchLine_117.result())
+SketchPoint_26 = Sketch_11.addPoint(12.81710695710752, 3)
+SketchPoint_26.setAuxiliary(True)
+SketchConstraintCoincidence_186 = Sketch_11.setCoincident(SketchPoint_26.coordinates(), SketchLine_117.result())
+SketchConstraintCoincidence_186.setName("SketchConstraintCoincidence_17")
+SketchConstraintDistance_23 = Sketch_11.setDistance(SketchPoint_26.coordinates(), SketchLine_107.result(), 3)
+SketchLine_118 = Sketch_11.addLine(28, 7.5, 29, 7.5)
+SketchLine_118.setName("SketchLine_14")
+SketchLine_118.result().setName("SketchLine_14")
+SketchConstraintCoincidence_187 = Sketch_11.setCoincident(SketchLine_111.startPoint(), SketchLine_118.startPoint())
+SketchConstraintCoincidence_187.setName("SketchConstraintCoincidence_18")
+SketchConstraintCoincidence_188 = Sketch_11.setCoincident(SketchLine_110.endPoint(), SketchLine_118.endPoint())
+SketchConstraintCoincidence_188.setName("SketchConstraintCoincidence_19")
+SketchConstraintLength_25 = Sketch_11.setLength(SketchLine_118.result(), 1)
+SketchConstraintLength_25.setName("SketchConstraintLength_9")
+SketchArc_25 = Sketch_11.addArc(14.78851987160339, 9.105317068618911, 10.426976887961, 4.40018070612629, 21.00014787857639, 7.5, False)
+SketchConstraintCoincidence_189 = Sketch_11.setCoincident(SketchLine_116.endPoint(), SketchArc_25.startPoint())
+SketchConstraintCoincidence_189.setName("SketchConstraintCoincidence_20")
+SketchConstraintCoincidence_190 = Sketch_11.setCoincident(SketchLine_113.endPoint(), SketchArc_25.endPoint())
+SketchConstraintCoincidence_190.setName("SketchConstraintCoincidence_21")
+SketchConstraintCoincidence_191 = Sketch_11.setCoincident(SketchPoint_26.coordinates(), SketchArc_25.results()[1])
+SketchConstraintCoincidence_191.setName("SketchConstraintCoincidence_22")
+SketchConstraintHorizontal_26 = Sketch_11.setHorizontal(SketchLine_118.result())
+SketchConstraintHorizontal_26.setName("SketchConstraintHorizontal_9")
+SketchConstraintDistance_24 = Sketch_11.setDistance(SketchLine_111.startPoint(), SketchLine_108.result(), 32)
+SketchConstraintDistance_24.setName("SketchConstraintDistance_9")
+model.do()
+Extrusion_2 = model.addExtrusion(Part_2_doc, [model.selection("WIRE", "Sketch_1/Wire-SketchLine_1f-SketchLine_3f-SketchLine_4f-SketchLine_5f-SketchLine_7f-SketchArc_1_2f-SketchLine_8f-SketchLine_9f-SketchLine_10r-SketchLine_11r-SketchLine_12r-SketchLine_14r-SketchArc_2_2r")], model.selection(), 12, 0)
+Sketch_12 = model.addSketch(Part_2_doc, model.selection("FACE", "PartSet/XOZ"))
+SketchArc_26 = Sketch_12.addArc(53.99996594708078, 6.000000000028422, 54, 12, 53.99994409538203, -3.231174267785264e-027, True)
+SketchLine_119 = Sketch_12.addLine(model.selection("EDGE", "Extrusion_1_1/Generated_Face_13&Extrusion_1_1/To_Face_1"))
+SketchLine_119.setName("SketchLine_15")
+SketchLine_119.result().setName("SketchLine_15")
+SketchConstraintCoincidence_192 = Sketch_12.setCoincident(SketchArc_26.startPoint(), SketchLine_119.result())
+SketchConstraintCoincidence_192.setName("SketchConstraintCoincidence_23")
+SketchLine_120 = Sketch_12.addLine(model.selection("EDGE", "Sketch_1/Edge-SketchLine_1"))
+SketchLine_120.setName("SketchLine_16")
+SketchLine_120.result().setName("SketchLine_16")
+SketchConstraintCoincidence_193 = Sketch_12.setCoincident(SketchArc_26.endPoint(), SketchLine_120.result())
+SketchConstraintCoincidence_193.setName("SketchConstraintCoincidence_24")
+SketchConstraintRadius_13 = Sketch_12.setRadius(SketchArc_26.results()[1], 6)
+SketchLine_121 = Sketch_12.addLine(model.selection("EDGE", "Extrusion_1_1/Generated_Face_13&Extrusion_1_1/Generated_Face_1"))
+SketchLine_121.setName("SketchLine_17")
+SketchLine_121.result().setName("SketchLine_17")
+SketchConstraintDistance_25 = Sketch_12.setDistance(SketchArc_26.startPoint(), SketchLine_121.result(), 6)
+SketchConstraintDistance_25.setName("SketchConstraintDistance_7")
+SketchLine_122 = Sketch_12.addLine(54, 12, 53.10174978726379, 13.92603605930655)
+SketchLine_122.setName("SketchLine_18")
+SketchLine_122.result().setName("SketchLine_18")
+SketchConstraintCoincidence_194 = Sketch_12.setCoincident(SketchArc_26.startPoint(), SketchLine_122.startPoint())
+SketchConstraintCoincidence_194.setName("SketchConstraintCoincidence_25")
+SketchLine_123 = Sketch_12.addLine(53.10174978726379, 13.92603605930655, 63.82610057919769, 13.82486293862793)
+SketchLine_123.setName("SketchLine_19")
+SketchLine_123.result().setName("SketchLine_19")
+SketchConstraintCoincidence_195 = Sketch_12.setCoincident(SketchLine_122.endPoint(), SketchLine_123.startPoint())
+SketchConstraintCoincidence_195.setName("SketchConstraintCoincidence_26")
+SketchLine_124 = Sketch_12.addLine(63.82610057919769, 13.82486293862793, 62.66260969139353, -3.07104821470189)
+SketchLine_124.setName("SketchLine_20")
+SketchLine_124.result().setName("SketchLine_20")
+SketchConstraintCoincidence_196 = Sketch_12.setCoincident(SketchLine_123.endPoint(), SketchLine_124.startPoint())
+SketchConstraintCoincidence_196.setName("SketchConstraintCoincidence_27")
+SketchLine_125 = Sketch_12.addLine(62.66260969139353, -3.07104821470189, 53.10174978726379, -2.868701973344648)
+SketchLine_125.setName("SketchLine_21")
+SketchLine_125.result().setName("SketchLine_21")
+SketchConstraintCoincidence_197 = Sketch_12.setCoincident(SketchLine_124.endPoint(), SketchLine_125.startPoint())
+SketchConstraintCoincidence_197.setName("SketchConstraintCoincidence_28")
+SketchLine_126 = Sketch_12.addLine(53.10174978726379, -2.868701973344648, 53.99994409538203, -3.231174267785264e-027)
+SketchLine_126.setName("SketchLine_22")
+SketchLine_126.result().setName("SketchLine_22")
+SketchConstraintCoincidence_198 = Sketch_12.setCoincident(SketchLine_125.endPoint(), SketchLine_126.startPoint())
+SketchConstraintCoincidence_198.setName("SketchConstraintCoincidence_29")
+SketchConstraintCoincidence_199 = Sketch_12.setCoincident(SketchArc_26.endPoint(), SketchLine_126.endPoint())
+SketchConstraintCoincidence_199.setName("SketchConstraintCoincidence_30")
+model.do()
+ExtrusionCut_10 = model.addExtrusionCut(Part_2_doc, [model.selection("FACE", "Sketch_2/Face-SketchArc_3_2r-SketchLine_18r-SketchLine_19r-SketchLine_20r-SketchLine_21r-SketchLine_22r")], model.selection(), 7, 15, [model.selection("SOLID", "Extrusion_1_1")])
+Sketch_13 = model.addSketch(Part_2_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_4"))
+SketchLine_127 = Sketch_13.addLine(28, -6, -4.270492394552598, -6.000000000000001)
+SketchLine_127.setName("SketchLine_23")
+SketchLine_127.result().setName("SketchLine_23")
+SketchLine_127.setAuxiliary(True)
+SketchLine_128 = Sketch_13.addLine(model.selection("EDGE", "Extrusion_1_1/Generated_Face_5&Extrusion_1_1/Generated_Face_4"))
+SketchLine_128.setName("SketchLine_24")
+SketchLine_128.result().setName("SketchLine_24")
+SketchConstraintCoincidence_200 = Sketch_13.setCoincident(SketchLine_127.startPoint(), SketchLine_128.result())
+SketchConstraintCoincidence_200.setName("SketchConstraintCoincidence_31")
+SketchConstraintHorizontal_27 = Sketch_13.setHorizontal(SketchLine_127.result())
+SketchLine_129 = Sketch_13.addLine(28, -6, 63.78468475453244, -6.000000000000001)
+SketchLine_129.setName("SketchLine_25")
+SketchLine_129.result().setName("SketchLine_25")
+SketchLine_129.setAuxiliary(True)
+SketchConstraintCoincidence_201 = Sketch_13.setCoincident(SketchLine_127.startPoint(), SketchLine_129.startPoint())
+SketchConstraintCoincidence_201.setName("SketchConstraintCoincidence_32")
+SketchConstraintHorizontal_28 = Sketch_13.setHorizontal(SketchLine_129.result())
+SketchLine_130 = Sketch_13.addLine(60, -1.500000000000001, 29, -1.500000000000001)
+SketchLine_130.setName("SketchLine_26")
+SketchLine_130.result().setName("SketchLine_26")
+SketchLine_131 = Sketch_13.addLine(29, -1.500000000000001, 29, -10.5)
+SketchLine_131.setName("SketchLine_27")
+SketchLine_131.result().setName("SketchLine_27")
+SketchLine_132 = Sketch_13.addLine(29, -10.5, 60, -10.5)
+SketchLine_132.setName("SketchLine_28")
+SketchLine_132.result().setName("SketchLine_28")
+SketchLine_133 = Sketch_13.addLine(60, -10.5, 60, -1.500000000000001)
+SketchLine_133.setName("SketchLine_29")
+SketchLine_133.result().setName("SketchLine_29")
+SketchConstraintCoincidence_202 = Sketch_13.setCoincident(SketchLine_133.endPoint(), SketchLine_130.startPoint())
+SketchConstraintCoincidence_202.setName("SketchConstraintCoincidence_33")
+SketchConstraintCoincidence_203 = Sketch_13.setCoincident(SketchLine_130.endPoint(), SketchLine_131.startPoint())
+SketchConstraintCoincidence_203.setName("SketchConstraintCoincidence_34")
+SketchConstraintCoincidence_204 = Sketch_13.setCoincident(SketchLine_131.endPoint(), SketchLine_132.startPoint())
+SketchConstraintCoincidence_204.setName("SketchConstraintCoincidence_35")
+SketchConstraintCoincidence_205 = Sketch_13.setCoincident(SketchLine_132.endPoint(), SketchLine_133.startPoint())
+SketchConstraintCoincidence_205.setName("SketchConstraintCoincidence_36")
+SketchConstraintHorizontal_29 = Sketch_13.setHorizontal(SketchLine_130.result())
+SketchConstraintVertical_25 = Sketch_13.setVertical(SketchLine_131.result())
+SketchConstraintHorizontal_30 = Sketch_13.setHorizontal(SketchLine_132.result())
+SketchConstraintVertical_26 = Sketch_13.setVertical(SketchLine_133.result())
+SketchLine_134 = Sketch_13.addLine(29, -10.5, 60, -1.500000000000001)
+SketchLine_134.setName("SketchLine_30")
+SketchLine_134.result().setName("SketchLine_30")
+SketchLine_134.setAuxiliary(True)
+SketchConstraintCoincidence_206 = Sketch_13.setCoincident(SketchLine_131.endPoint(), SketchLine_134.startPoint())
+SketchConstraintCoincidence_206.setName("SketchConstraintCoincidence_37")
+SketchConstraintCoincidence_207 = Sketch_13.setCoincident(SketchLine_132.startPoint(), SketchLine_134.startPoint())
+SketchConstraintCoincidence_207.setName("SketchConstraintCoincidence_38")
+SketchConstraintCoincidence_208 = Sketch_13.setCoincident(SketchLine_130.startPoint(), SketchLine_134.endPoint())
+SketchConstraintCoincidence_208.setName("SketchConstraintCoincidence_39")
+SketchConstraintCoincidence_209 = Sketch_13.setCoincident(SketchLine_133.endPoint(), SketchLine_134.endPoint())
+SketchConstraintCoincidence_209.setName("SketchConstraintCoincidence_40")
+SketchLine_135 = Sketch_13.addLine(29, -1.500000000000001, 60, -10.5)
+SketchLine_135.setName("SketchLine_31")
+SketchLine_135.result().setName("SketchLine_31")
+SketchLine_135.setAuxiliary(True)
+SketchConstraintCoincidence_210 = Sketch_13.setCoincident(SketchLine_130.endPoint(), SketchLine_135.startPoint())
+SketchConstraintCoincidence_210.setName("SketchConstraintCoincidence_41")
+SketchConstraintCoincidence_211 = Sketch_13.setCoincident(SketchLine_131.startPoint(), SketchLine_135.startPoint())
+SketchConstraintCoincidence_211.setName("SketchConstraintCoincidence_42")
+SketchConstraintCoincidence_212 = Sketch_13.setCoincident(SketchLine_132.endPoint(), SketchLine_135.endPoint())
+SketchConstraintCoincidence_212.setName("SketchConstraintCoincidence_43")
+SketchConstraintCoincidence_213 = Sketch_13.setCoincident(SketchLine_133.startPoint(), SketchLine_135.endPoint())
+SketchConstraintCoincidence_213.setName("SketchConstraintCoincidence_44")
+SketchPoint_27 = Sketch_13.addPoint(44.5, -6.000000000000001)
+SketchPoint_27.setAuxiliary(True)
+SketchConstraintCoincidence_214 = Sketch_13.setCoincident(SketchPoint_27.coordinates(), SketchLine_135.result())
+SketchConstraintCoincidence_214.setName("SketchConstraintCoincidence_45")
+SketchConstraintMiddle_9 = Sketch_13.setMiddlePoint(SketchPoint_27.coordinates(), SketchLine_135.result())
+SketchConstraintCoincidence_215 = Sketch_13.setCoincident(SketchPoint_27.coordinates(), SketchLine_129.result())
+SketchConstraintCoincidence_215.setName("SketchConstraintCoincidence_46")
+SketchConstraintDistance_26 = Sketch_13.setDistance(SketchLine_128.startPoint(), SketchLine_129.result(), 6)
+SketchConstraintDistance_26.setName("SketchConstraintDistance_8")
+SketchConstraintLength_26 = Sketch_13.setLength(SketchLine_133.result(), 9)
+SketchConstraintLength_26.setName("SketchConstraintLength_10")
+SketchLine_136 = Sketch_13.addLine(21.00014787857639, -1.499999999999999, 12.00014787857639, -1.499999999999999)
+SketchLine_136.setName("SketchLine_32")
+SketchLine_136.result().setName("SketchLine_32")
+SketchLine_137 = Sketch_13.addLine(12.00014787857639, -1.499999999999999, 12.00014787857639, -10.5)
+SketchLine_137.setName("SketchLine_33")
+SketchLine_137.result().setName("SketchLine_33")
+SketchLine_138 = Sketch_13.addLine(12.00014787857639, -10.5, 21.00014787857639, -10.5)
+SketchLine_138.setName("SketchLine_34")
+SketchLine_138.result().setName("SketchLine_34")
+SketchLine_139 = Sketch_13.addLine(21.00014787857639, -10.5, 21.00014787857639, -1.499999999999999)
+SketchLine_139.setName("SketchLine_35")
+SketchLine_139.result().setName("SketchLine_35")
+SketchConstraintCoincidence_216 = Sketch_13.setCoincident(SketchLine_139.endPoint(), SketchLine_136.startPoint())
+SketchConstraintCoincidence_216.setName("SketchConstraintCoincidence_47")
+SketchConstraintCoincidence_217 = Sketch_13.setCoincident(SketchLine_136.endPoint(), SketchLine_137.startPoint())
+SketchConstraintCoincidence_217.setName("SketchConstraintCoincidence_48")
+SketchConstraintCoincidence_218 = Sketch_13.setCoincident(SketchLine_137.endPoint(), SketchLine_138.startPoint())
+SketchConstraintCoincidence_218.setName("SketchConstraintCoincidence_49")
+SketchConstraintCoincidence_219 = Sketch_13.setCoincident(SketchLine_138.endPoint(), SketchLine_139.startPoint())
+SketchConstraintCoincidence_219.setName("SketchConstraintCoincidence_50")
+SketchConstraintHorizontal_31 = Sketch_13.setHorizontal(SketchLine_136.result())
+SketchConstraintHorizontal_31.setName("SketchConstraintHorizontal_10")
+SketchConstraintVertical_27 = Sketch_13.setVertical(SketchLine_137.result())
+SketchConstraintHorizontal_32 = Sketch_13.setHorizontal(SketchLine_138.result())
+SketchConstraintHorizontal_32.setName("SketchConstraintHorizontal_11")
+SketchConstraintVertical_28 = Sketch_13.setVertical(SketchLine_139.result())
+SketchConstraintEqual_4 = Sketch_13.setEqual(SketchLine_131.result(), SketchLine_139.result())
+SketchLine_140 = Sketch_13.addLine(12.00014787857639, -10.5, 21.00014787857639, -1.499999999999999)
+SketchLine_140.setName("SketchLine_36")
+SketchLine_140.result().setName("SketchLine_36")
+SketchLine_140.setAuxiliary(True)
+SketchConstraintCoincidence_220 = Sketch_13.setCoincident(SketchLine_137.endPoint(), SketchLine_140.startPoint())
+SketchConstraintCoincidence_220.setName("SketchConstraintCoincidence_51")
+SketchConstraintCoincidence_221 = Sketch_13.setCoincident(SketchLine_138.startPoint(), SketchLine_140.startPoint())
+SketchConstraintCoincidence_221.setName("SketchConstraintCoincidence_52")
+SketchConstraintCoincidence_222 = Sketch_13.setCoincident(SketchLine_136.startPoint(), SketchLine_140.endPoint())
+SketchConstraintCoincidence_222.setName("SketchConstraintCoincidence_53")
+SketchConstraintCoincidence_223 = Sketch_13.setCoincident(SketchLine_139.endPoint(), SketchLine_140.endPoint())
+SketchConstraintCoincidence_223.setName("SketchConstraintCoincidence_54")
+SketchPoint_28 = Sketch_13.addPoint(16.50014787857639, -5.999999999999999)
+SketchPoint_28.setAuxiliary(True)
+SketchConstraintCoincidence_224 = Sketch_13.setCoincident(SketchPoint_28.coordinates(), SketchLine_140.result())
+SketchConstraintCoincidence_224.setName("SketchConstraintCoincidence_55")
+SketchConstraintMiddle_10 = Sketch_13.setMiddlePoint(SketchLine_140.result(), SketchPoint_28.coordinates())
+SketchConstraintCoincidence_225 = Sketch_13.setCoincident(SketchPoint_28.coordinates(), SketchLine_127.result())
+SketchConstraintCoincidence_225.setName("SketchConstraintCoincidence_56")
+SketchLine_141 = Sketch_13.addLine(model.selection("EDGE", "Extrusion_1_1/Generated_Face_4&ExtrusionCut_1_1/Modfied_4"))
+SketchLine_141.setName("SketchLine_37")
+SketchLine_141.result().setName("SketchLine_37")
+SketchConstraintCoincidence_226 = Sketch_13.setCoincident(SketchLine_131.startPoint(), SketchLine_141.result())
+SketchConstraintCoincidence_226.setName("SketchConstraintCoincidence_57")
+SketchConstraintLength_27 = Sketch_13.setLength(SketchLine_130.result(), 31)
+SketchConstraintLength_27.setName("SketchConstraintLength_11")
+SketchLine_142 = Sketch_13.addLine(model.selection("EDGE", "Extrusion_1_1/Generated_Face_9&Extrusion_1_1/Generated_Face_8"))
+SketchLine_142.setName("SketchLine_38")
+SketchLine_142.result().setName("SketchLine_38")
+SketchConstraintCoincidence_227 = Sketch_13.setCoincident(SketchLine_136.startPoint(), SketchLine_142.result())
+SketchConstraintCoincidence_227.setName("SketchConstraintCoincidence_58")
+SketchConstraintEqual_5 = Sketch_13.setEqual(SketchLine_136.result(), SketchLine_131.result())
+model.do()
+ExtrusionCut_11 = model.addExtrusionCut(Part_2_doc, [model.selection("FACE", "Sketch_3/Face-SketchLine_32f-SketchLine_33f-SketchLine_34f-SketchLine_35f"), model.selection("FACE", "Sketch_3/Face-SketchLine_26f-SketchLine_27f-SketchLine_28f-SketchLine_29f")], model.selection(), model.selection("FACE", "ExtrusionCut_1_1/Modfied_3"), 0, model.selection(), 0, [model.selection("SOLID", "ExtrusionCut_1_1")])
+Sketch_14 = model.addSketch(Part_2_doc, model.selection("FACE", "ExtrusionCut_1_1/Modfied_1"))
+SketchLine_143 = Sketch_14.addLine(0.4324637622511017, 3.581086955422081, 1.55585595716119, 2.812450190483599)
+SketchLine_143.setName("SketchLine_39")
+SketchLine_143.result().setName("SketchLine_39")
+SketchLine_144 = Sketch_14.addLine(model.selection("EDGE", "ExtrusionCut_1_1/Modfied_1&Extrusion_1_1/Generated_Face_11"))
+SketchLine_144.setName("SketchLine_40")
+SketchLine_144.result().setName("SketchLine_40")
+SketchConstraintCoincidence_228 = Sketch_14.setCoincident(SketchLine_143.startPoint(), SketchLine_144.result())
+SketchConstraintCoincidence_228.setName("SketchConstraintCoincidence_59")
+SketchLine_145 = Sketch_14.addLine(1.55585595716119, 2.812450190483599, 2.324492722099671, 3.935842385393688)
+SketchLine_145.setName("SketchLine_41")
+SketchLine_145.result().setName("SketchLine_41")
+SketchConstraintCoincidence_229 = Sketch_14.setCoincident(SketchLine_143.endPoint(), SketchLine_145.startPoint())
+SketchConstraintCoincidence_229.setName("SketchConstraintCoincidence_60")
+SketchConstraintCoincidence_230 = Sketch_14.setCoincident(SketchLine_145.endPoint(), SketchLine_144.result())
+SketchConstraintCoincidence_230.setName("SketchConstraintCoincidence_61")
+SketchLine_146 = Sketch_14.addLine(2.324492722099671, 3.935842385393688, 0.4324637622511017, 3.581086955422081)
+SketchLine_146.setName("SketchLine_42")
+SketchLine_146.result().setName("SketchLine_42")
+SketchConstraintCoincidence_231 = Sketch_14.setCoincident(SketchLine_145.endPoint(), SketchLine_146.startPoint())
+SketchConstraintCoincidence_231.setName("SketchConstraintCoincidence_62")
+SketchConstraintCoincidence_232 = Sketch_14.setCoincident(SketchLine_143.startPoint(), SketchLine_146.endPoint())
+SketchConstraintCoincidence_232.setName("SketchConstraintCoincidence_63")
+SketchConstraintLength_28 = Sketch_14.setLength(SketchLine_146.result(), 1.925)
+SketchConstraintLength_28.setName("SketchConstraintLength_12")
+SketchConstraintEqual_6 = Sketch_14.setEqual(SketchLine_143.result(), SketchLine_145.result())
+SketchConstraintPerpendicular_2 = Sketch_14.setPerpendicular(SketchLine_143.result(), SketchLine_145.result())
+SketchConstraintDistance_27 = Sketch_14.setDistance(SketchLine_144.startPoint(), SketchLine_143.startPoint(), 0.44)
+SketchMultiTranslation_3_objects = [SketchLine_143.result(), SketchLine_146.result(), SketchLine_145.result()]
+SketchMultiTranslation_3 = Sketch_14.addTranslation(SketchMultiTranslation_3_objects, SketchLine_146.startPoint(), SketchLine_144.endPoint(), 4, True)
+[SketchLine_147, SketchLine_148, SketchLine_149, SketchLine_150, SketchLine_151, SketchLine_152, SketchLine_153, SketchLine_154, SketchLine_155] = SketchMultiTranslation_3.translated()
+SketchLine_155.setName("SketchLine_51")
+SketchLine_155.result().setName("SketchLine_51")
+SketchLine_154.setName("SketchLine_50")
+SketchLine_154.result().setName("SketchLine_50")
+SketchLine_153.setName("SketchLine_45")
+SketchLine_153.result().setName("SketchLine_45")
+SketchLine_152.setName("SketchLine_49")
+SketchLine_152.result().setName("SketchLine_49")
+SketchLine_151.setName("SketchLine_48")
+SketchLine_151.result().setName("SketchLine_48")
+SketchLine_150.setName("SketchLine_46")
+SketchLine_150.result().setName("SketchLine_46")
+SketchLine_149.setName("SketchLine_47")
+SketchLine_149.result().setName("SketchLine_47")
+SketchLine_148.setName("SketchLine_46")
+SketchLine_148.result().setName("SketchLine_46")
+SketchLine_147.setName("SketchLine_43")
+SketchLine_147.result().setName("SketchLine_43")
+model.do()
+ExtrusionCut_12 = model.addExtrusionCut(Part_2_doc, [model.selection("COMPOUND", "Sketch_4")], model.selection(), model.selection("FACE", "ExtrusionCut_1_1/Modfied_2"), 0, model.selection(), 0, [model.selection("SOLID", "ExtrusionCut_2_1")])
+Plane_9 = model.addPlane(Part_2_doc, model.selection("VERTEX", "ExtrusionCut_1_1/Modfied_5&ExtrusionCut_3_1/Modfied_3&Extrusion_1_1/Generated_Face_12"), model.selection("VERTEX", "ExtrusionCut_3_1/Modfied_3&Extrusion_1_1/Generated_Face_7&Extrusion_1_1/Generated_Face_6"), model.selection("VERTEX", "ExtrusionCut_1_1/Modfied_5&ExtrusionCut_2_1/Modfied_9&ExtrusionCut_3_1/Modfied_3"))
+Sketch_15 = model.addSketch(Part_2_doc, model.selection("FACE", "Plane_1"))
+SketchArc_27 = Sketch_15.addArc(25.00007393928819, -7.521062532210847, 22.00014787857639, -7.5, 28, -7.5, True)
+SketchPoint_29 = Sketch_15.addPoint(22.00014787857639, -7.5)
+SketchConstraintRigid_14 = Sketch_15.setFixed(SketchPoint_29.result())
+SketchConstraintRigid_14.setName("SketchConstraintRigid_10")
+SketchConstraintCoincidence_233 = Sketch_15.setCoincident(SketchArc_27.startPoint(), SketchPoint_29.result())
+SketchConstraintCoincidence_233.setName("SketchConstraintCoincidence_64")
+SketchPoint_30 = Sketch_15.addPoint(28, -7.5)
+SketchConstraintRigid_15 = Sketch_15.setFixed(SketchPoint_30.result())
+SketchConstraintRigid_15.setName("SketchConstraintRigid_11")
+SketchConstraintCoincidence_234 = Sketch_15.setCoincident(SketchArc_27.endPoint(), SketchPoint_30.result())
+SketchConstraintCoincidence_234.setName("SketchConstraintCoincidence_65")
+SketchConstraintRadius_14 = Sketch_15.setRadius(SketchArc_27.results()[1], 3)
+SketchLine_156 = Sketch_15.addLine(22.00014787857639, -7.5, 22.00014787857639, -11.56094005408083)
+SketchLine_156.setName("SketchLine_52")
+SketchLine_156.result().setName("SketchLine_52")
+SketchConstraintCoincidence_235 = Sketch_15.setCoincident(SketchArc_27.startPoint(), SketchLine_156.startPoint())
+SketchConstraintCoincidence_235.setName("SketchConstraintCoincidence_66")
+SketchConstraintCoincidence_236 = Sketch_15.setCoincident(SketchPoint_29.coordinates(), SketchLine_156.startPoint())
+SketchConstraintCoincidence_236.setName("SketchConstraintCoincidence_67")
+SketchLine_157 = Sketch_15.addLine(22.00014787857639, -11.56094005408083, 28, -11.56094005408083)
+SketchLine_157.setName("SketchLine_53")
+SketchLine_157.result().setName("SketchLine_53")
+SketchConstraintCoincidence_237 = Sketch_15.setCoincident(SketchLine_156.endPoint(), SketchLine_157.startPoint())
+SketchConstraintCoincidence_237.setName("SketchConstraintCoincidence_68")
+SketchLine_158 = Sketch_15.addLine(28, -11.56094005408083, 28, -7.5)
+SketchLine_158.setName("SketchLine_54")
+SketchLine_158.result().setName("SketchLine_54")
+SketchConstraintCoincidence_238 = Sketch_15.setCoincident(SketchLine_157.endPoint(), SketchLine_158.startPoint())
+SketchConstraintCoincidence_238.setName("SketchConstraintCoincidence_69")
+SketchConstraintCoincidence_239 = Sketch_15.setCoincident(SketchArc_27.endPoint(), SketchLine_158.endPoint())
+SketchConstraintCoincidence_239.setName("SketchConstraintCoincidence_70")
+SketchConstraintCoincidence_240 = Sketch_15.setCoincident(SketchPoint_30.coordinates(), SketchLine_158.endPoint())
+SketchConstraintCoincidence_240.setName("SketchConstraintCoincidence_71")
+SketchConstraintVertical_29 = Sketch_15.setVertical(SketchLine_156.result())
+SketchConstraintVertical_30 = Sketch_15.setVertical(SketchLine_158.result())
+SketchConstraintHorizontal_33 = Sketch_15.setHorizontal(SketchLine_157.result())
+SketchConstraintHorizontal_33.setName("SketchConstraintHorizontal_12")
+model.do()
+Plane_10 = model.addPlane(Part_2_doc, model.selection("FACE", "ExtrusionCut_3_1/Modfied_3"), 6, True)
+Plane_11 = model.addPlane(Part_2_doc, model.selection("FACE", "Plane_2"), 3, True)
+ExtrusionCut_13 = model.addExtrusionCut(Part_2_doc, [model.selection("FACE", "Sketch_5/Face-SketchArc_4_2f-SketchLine_52f-SketchLine_53f-SketchLine_54f")], model.selection(), 3, 0, [model.selection("SOLID", "ExtrusionCut_3_1")])
+ExtrusionCut_14 = model.addExtrusionCut(Part_2_doc, [model.selection("FACE", "Sketch_5/Face-SketchArc_4_2f-SketchLine_52f-SketchLine_53f-SketchLine_54f")], model.selection(), model.selection("FACE", "Plane_3"), 0, model.selection("FACE", "Plane_2"), 0, [model.selection("SOLID", "ExtrusionCut_4_1")])
+Sketch_16 = model.addSketch(Part_2_doc, model.selection("FACE", "ExtrusionCut_4_1/Modfied_6"))
+SketchArc_28 = Sketch_16.addArc(45.99999999999999, 0, 45.49999999999999, 8.91700958118717e-020, 46.49999999999999, 8.280962276646116e-019, False)
+SketchLine_159 = Sketch_16.addLine(0, 0, 54, 0)
+SketchLine_159.setName("SketchLine_55")
+SketchLine_159.result().setName("SketchLine_55")
+SketchConstraintRigid_16 = Sketch_16.setFixed(SketchLine_159.result())
+SketchConstraintRigid_16.setName("SketchConstraintRigid_12")
+SketchConstraintCoincidence_241 = Sketch_16.setCoincident(SketchArc_28.center(), SketchLine_159.result())
+SketchConstraintCoincidence_241.setName("SketchConstraintCoincidence_72")
+SketchConstraintCoincidence_242 = Sketch_16.setCoincident(SketchArc_28.startPoint(), SketchLine_159.result())
+SketchConstraintCoincidence_242.setName("SketchConstraintCoincidence_73")
+SketchConstraintCoincidence_243 = Sketch_16.setCoincident(SketchArc_28.endPoint(), SketchLine_159.result())
+SketchConstraintCoincidence_243.setName("SketchConstraintCoincidence_74")
+SketchLine_160 = Sketch_16.addLine(45.49999999999999, 8.91700958118717e-020, 46.49999999999999, 8.280962276646116e-019)
+SketchLine_160.setName("SketchLine_56")
+SketchLine_160.result().setName("SketchLine_56")
+SketchConstraintCoincidence_244 = Sketch_16.setCoincident(SketchArc_28.startPoint(), SketchLine_160.startPoint())
+SketchConstraintCoincidence_244.setName("SketchConstraintCoincidence_75")
+SketchConstraintCoincidence_245 = Sketch_16.setCoincident(SketchArc_28.endPoint(), SketchLine_160.endPoint())
+SketchConstraintCoincidence_245.setName("SketchConstraintCoincidence_76")
+SketchConstraintRadius_15 = Sketch_16.setRadius(SketchArc_28.results()[1], 0.5)
+SketchLine_161 = Sketch_16.addLine(0, 0, 0, 3.499999999999999)
+SketchLine_161.setName("SketchLine_57")
+SketchLine_161.result().setName("SketchLine_57")
+SketchConstraintDistance_28 = Sketch_16.setDistance(SketchArc_28.center(), SketchLine_161.result(), 46)
+SketchConstraintRigid_17 = Sketch_16.setFixed(SketchLine_161.result())
+SketchConstraintRigid_17.setName("SketchConstraintRigid_13")
+SketchPoint_31 = Sketch_16.addPoint(58, 0)
+SketchConstraintCoincidence_246 = Sketch_16.setCoincident(SketchPoint_31.coordinates(), SketchLine_159.result())
+SketchConstraintCoincidence_246.setName("SketchConstraintCoincidence_77")
+SketchConstraintDistance_29 = Sketch_16.setDistance(SketchArc_28.center(), SketchPoint_31.coordinates(), 12)
+SketchMultiTranslation_4 = Sketch_16.addTranslation([SketchLine_160.result(), SketchArc_28.results()[1]], SketchArc_28.center(), SketchPoint_31.coordinates(), 9, True)
+[SketchLine_162, SketchLine_163, SketchLine_164, SketchLine_165, SketchLine_166, SketchLine_167, SketchLine_168, SketchLine_169, SketchArc_29, SketchArc_30, SketchArc_31, SketchArc_32, SketchArc_33, SketchArc_34, SketchArc_35, SketchArc_36] = SketchMultiTranslation_4.translated()
+SketchLine_169.setName("SketchLine_65")
+SketchLine_169.result().setName("SketchLine_65")
+SketchLine_168.setName("SketchLine_64")
+SketchLine_168.result().setName("SketchLine_64")
+SketchLine_167.setName("SketchLine_63")
+SketchLine_167.result().setName("SketchLine_63")
+SketchLine_166.setName("SketchLine_62")
+SketchLine_166.result().setName("SketchLine_62")
+SketchLine_165.setName("SketchLine_61")
+SketchLine_165.result().setName("SketchLine_61")
+SketchLine_164.setName("SketchLine_60")
+SketchLine_164.result().setName("SketchLine_60")
+SketchLine_163.setName("SketchLine_59")
+SketchLine_163.result().setName("SketchLine_59")
+SketchLine_162.setName("SketchLine_58")
+SketchLine_162.result().setName("SketchLine_58")
+model.do()
+ExtrusionFuse_2 = model.addExtrusionFuse(Part_2_doc, [model.selection("COMPOUND", "Sketch_6")], model.selection(), model.selection("FACE", "Sketch_1/Face-SketchLine_1f-SketchLine_3f-SketchLine_4f-SketchLine_5f-SketchLine_7f-SketchArc_1_2f-SketchLine_8f-SketchLine_9f-SketchLine_10r-SketchLine_11r-SketchLine_12r-SketchLine_14r-SketchArc_2_2r"), 0, model.selection(), 0, [model.selection("SOLID", "ExtrusionCut_5_1")])
+Sketch_17 = model.addSketch(Part_2_doc, model.selection("FACE", "ExtrusionCut_2_1/Modfied_12"))
+SketchLine_170 = Sketch_17.addLine(50.25000000000001, -4.5, 31.24999999998802, -4.499999999999997)
+SketchLine_170.setName("SketchLine_76")
+SketchLine_170.result().setName("SketchLine_76")
+SketchLine_171 = Sketch_17.addLine(51.00000000000001, -6.749999999999998, 51.00000000000001, -5.24999997149696)
+SketchLine_171.setName("SketchLine_78")
+SketchLine_171.result().setName("SketchLine_78")
+SketchLine_172 = Sketch_17.addLine(31, -4.750000022881151, 31, -7.249999999972618)
+SketchLine_172.setName("SketchLine_80")
+SketchLine_172.result().setName("SketchLine_80")
+SketchLine_173 = Sketch_17.addLine(31.25000000003855, -7.5, 50.24999994039248, -7.5)
+SketchLine_173.setName("SketchLine_79")
+SketchLine_173.result().setName("SketchLine_79")
+SketchLine_174 = Sketch_17.addLine(51, -4.5, 31, -4.5)
+SketchLine_174.setName("SketchLine_66")
+SketchLine_174.result().setName("SketchLine_66")
+SketchLine_174.setAuxiliary(True)
+SketchLine_175 = Sketch_17.addLine(51, -7.5, 51, -4.5)
+SketchLine_175.setAuxiliary(True)
+SketchConstraintCoincidence_247 = Sketch_17.setCoincident(SketchLine_175.endPoint(), SketchLine_174.startPoint())
+SketchConstraintCoincidence_247.setName("SketchConstraintCoincidence_78")
+SketchLine_176 = Sketch_17.addLine(31, -4.5, 31, -7.5)
+SketchLine_176.setName("SketchLine_67")
+SketchLine_176.result().setName("SketchLine_67")
+SketchLine_176.setAuxiliary(True)
+SketchConstraintCoincidence_248 = Sketch_17.setCoincident(SketchLine_174.endPoint(), SketchLine_176.startPoint())
+SketchConstraintCoincidence_248.setName("SketchConstraintCoincidence_79")
+SketchLine_177 = Sketch_17.addLine(31, -7.5, 51, -7.5)
+SketchLine_177.setName("SketchLine_68")
+SketchLine_177.result().setName("SketchLine_68")
+SketchLine_177.setAuxiliary(True)
+SketchConstraintCoincidence_249 = Sketch_17.setCoincident(SketchLine_176.endPoint(), SketchLine_177.startPoint())
+SketchConstraintCoincidence_249.setName("SketchConstraintCoincidence_80")
+SketchConstraintCoincidence_250 = Sketch_17.setCoincident(SketchLine_177.endPoint(), SketchLine_175.startPoint())
+SketchConstraintCoincidence_250.setName("SketchConstraintCoincidence_81")
+SketchConstraintHorizontal_34 = Sketch_17.setHorizontal(SketchLine_174.result())
+SketchConstraintHorizontal_34.setName("SketchConstraintHorizontal_13")
+SketchConstraintVertical_31 = Sketch_17.setVertical(SketchLine_176.result())
+SketchConstraintHorizontal_35 = Sketch_17.setHorizontal(SketchLine_177.result())
+SketchConstraintHorizontal_35.setName("SketchConstraintHorizontal_14")
+SketchConstraintVertical_32 = Sketch_17.setVertical(SketchLine_175.result())
+SketchLine_178 = Sketch_17.addLine(31, -7.5, 51, -4.5)
+SketchLine_178.setName("SketchLine_70")
+SketchLine_178.result().setName("SketchLine_70")
+SketchLine_178.setAuxiliary(True)
+SketchConstraintCoincidence_251 = Sketch_17.setCoincident(SketchLine_176.endPoint(), SketchLine_178.startPoint())
+SketchConstraintCoincidence_251.setName("SketchConstraintCoincidence_82")
+SketchConstraintCoincidence_252 = Sketch_17.setCoincident(SketchLine_177.startPoint(), SketchLine_178.startPoint())
+SketchConstraintCoincidence_252.setName("SketchConstraintCoincidence_83")
+SketchPoint_32 = Sketch_17.addPoint(51, -4.5)
+SketchConstraintCoincidence_253 = Sketch_17.setCoincident(SketchLine_174.startPoint(), SketchPoint_32.coordinates())
+SketchConstraintCoincidence_253.setName("SketchConstraintCoincidence_84")
+SketchConstraintCoincidence_254 = Sketch_17.setCoincident(SketchLine_175.endPoint(), SketchPoint_32.coordinates())
+SketchConstraintCoincidence_254.setName("SketchConstraintCoincidence_85")
+SketchPoint_33 = Sketch_17.addPoint(41, -6)
+SketchPoint_33.setAuxiliary(True)
+SketchConstraintCoincidence_255 = Sketch_17.setCoincident(SketchPoint_33.coordinates(), SketchLine_178.result())
+SketchConstraintCoincidence_255.setName("SketchConstraintCoincidence_86")
+SketchConstraintMiddle_11 = Sketch_17.setMiddlePoint(SketchLine_178.result(), SketchPoint_33.coordinates())
+SketchPoint_34 = Sketch_17.addPoint(21.00014787857639, -5.999999999999999)
+SketchPoint_34.setAuxiliary(True)
+SketchLine_179 = Sketch_17.addLine(21.00014787857639, -10.5, 21.00014787857639, -1.499999999999999)
+SketchLine_179.setName("SketchLine_71")
+SketchLine_179.result().setName("SketchLine_71")
+SketchConstraintRigid_18 = Sketch_17.setFixed(SketchLine_179.result())
+SketchConstraintRigid_18.setName("SketchConstraintRigid_14")
+SketchConstraintCoincidence_256 = Sketch_17.setCoincident(SketchPoint_34.coordinates(), SketchLine_179.result())
+SketchConstraintCoincidence_256.setName("SketchConstraintCoincidence_87")
+SketchConstraintMiddle_12 = Sketch_17.setMiddlePoint(SketchPoint_34.coordinates(), SketchLine_179.result())
+SketchLine_180 = Sketch_17.addLine(21.00014787857639, -6, 41, -5.999999999999999)
+SketchLine_180.setName("SketchLine_72")
+SketchLine_180.result().setName("SketchLine_72")
+SketchLine_180.setAuxiliary(True)
+SketchConstraintCoincidence_257 = Sketch_17.setCoincident(SketchPoint_34.coordinates(), SketchLine_180.startPoint())
+SketchConstraintCoincidence_257.setName("SketchConstraintCoincidence_88")
+SketchConstraintCoincidence_258 = Sketch_17.setCoincident(SketchPoint_33.coordinates(), SketchLine_180.endPoint())
+SketchConstraintCoincidence_258.setName("SketchConstraintCoincidence_89")
+SketchConstraintHorizontal_36 = Sketch_17.setHorizontal(SketchLine_180.result())
+SketchConstraintHorizontal_36.setName("SketchConstraintHorizontal_15")
+SketchConstraintCoincidence_259 = Sketch_17.setCoincident(SketchLine_178.endPoint(), SketchLine_174.startPoint())
+SketchConstraintCoincidence_259.setName("SketchConstraintCoincidence_90")
+SketchConstraintLength_29 = Sketch_17.setLength(SketchLine_175.result(), 3)
+SketchConstraintLength_29.setName("SketchConstraintLength_13")
+SketchConstraintLength_30 = Sketch_17.setLength(SketchLine_174.result(), 20)
+SketchConstraintLength_30.setName("SketchConstraintLength_14")
+SketchPoint_35 = Sketch_17.addPoint(29, -10.5)
+SketchConstraintDistance_30 = Sketch_17.setDistance(SketchPoint_35.coordinates(), SketchLine_176.result(), 2)
+SketchConstraintRigid_19 = Sketch_17.setFixed(SketchPoint_35.result())
+SketchConstraintRigid_19.setName("SketchConstraintRigid_15")
+SketchArc_37 = Sketch_17.addArc(50.24999999999999, -5.250000000000003, 51.00000000000001, -5.24999997149696, 50.25000000000001, -4.5, False)
+SketchLine_181 = Sketch_17.addLine(51, -7.5, 51.00000000000001, -5.24999997149696)
+SketchLine_181.setName("SketchLine_74")
+SketchLine_181.result().setName("SketchLine_74")
+SketchLine_181.setAuxiliary(True)
+SketchConstraintCoincidence_260 = Sketch_17.setCoincident(SketchArc_37.startPoint(), SketchLine_181.endPoint())
+SketchConstraintCoincidence_260.setName("SketchConstraintCoincidence_91")
+SketchLine_182 = Sketch_17.addLine(50.25000000000001, -4.5, 31, -4.5)
+SketchLine_182.setName("SketchLine_73")
+SketchLine_182.result().setName("SketchLine_73")
+SketchLine_182.setAuxiliary(True)
+SketchConstraintCoincidence_261 = Sketch_17.setCoincident(SketchArc_37.endPoint(), SketchLine_182.startPoint())
+SketchConstraintCoincidence_261.setName("SketchConstraintCoincidence_92")
+SketchConstraintTangent_15 = Sketch_17.setTangent(SketchArc_37.results()[1], SketchLine_182.result())
+SketchConstraintTangent_16 = Sketch_17.setTangent(SketchArc_37.results()[1], SketchLine_181.result())
+SketchConstraintCoincidence_262 = Sketch_17.setCoincident(SketchLine_174.endPoint(), SketchLine_182.endPoint())
+SketchConstraintCoincidence_262.setName("SketchConstraintCoincidence_93")
+SketchConstraintCoincidence_263 = Sketch_17.setCoincident(SketchLine_175.startPoint(), SketchLine_181.startPoint())
+SketchConstraintCoincidence_263.setName("SketchConstraintCoincidence_94")
+SketchConstraintCoincidence_264 = Sketch_17.setCoincident(SketchLine_182.startPoint(), SketchLine_174.result())
+SketchConstraintCoincidence_264.setName("SketchConstraintCoincidence_95")
+SketchConstraintCoincidence_265 = Sketch_17.setCoincident(SketchLine_181.endPoint(), SketchLine_175.result())
+SketchConstraintCoincidence_265.setName("SketchConstraintCoincidence_96")
+SketchArc_38 = Sketch_17.addArc(31.25000000000067, -4.750000000000669, 31.24999999998802, -4.499999999999997, 31, -4.750000022881151, False)
+SketchConstraintCoincidence_266 = Sketch_17.setCoincident(SketchArc_38.startPoint(), SketchLine_170.endPoint())
+SketchConstraintCoincidence_266.setName("SketchConstraintCoincidence_97")
+SketchLine_183 = Sketch_17.addLine(31, -4.750000022881151, 31, -7.5)
+SketchLine_183.setName("SketchLine_75")
+SketchLine_183.result().setName("SketchLine_75")
+SketchLine_183.setAuxiliary(True)
+SketchConstraintCoincidence_267 = Sketch_17.setCoincident(SketchArc_38.endPoint(), SketchLine_183.startPoint())
+SketchConstraintCoincidence_267.setName("SketchConstraintCoincidence_98")
+SketchConstraintTangent_17 = Sketch_17.setTangent(SketchArc_38.results()[1], SketchLine_183.result())
+SketchConstraintTangent_18 = Sketch_17.setTangent(SketchArc_38.results()[1], SketchLine_170.result())
+SketchConstraintCoincidence_268 = Sketch_17.setCoincident(SketchLine_176.endPoint(), SketchLine_183.endPoint())
+SketchConstraintCoincidence_268.setName("SketchConstraintCoincidence_99")
+SketchConstraintCoincidence_269 = Sketch_17.setCoincident(SketchLine_182.startPoint(), SketchLine_170.startPoint())
+SketchConstraintCoincidence_269.setName("SketchConstraintCoincidence_100")
+SketchConstraintCoincidence_270 = Sketch_17.setCoincident(SketchLine_183.startPoint(), SketchLine_176.result())
+SketchConstraintCoincidence_270.setName("SketchConstraintCoincidence_101")
+SketchConstraintCoincidence_271 = Sketch_17.setCoincident(SketchLine_170.endPoint(), SketchLine_182.result())
+SketchConstraintCoincidence_271.setName("SketchConstraintCoincidence_102")
+SketchArc_39 = Sketch_17.addArc(50.25, -6.749999999999999, 50.24999994039248, -7.5, 51.00000000000001, -6.749999999999998, False)
+SketchLine_184 = Sketch_17.addLine(31, -7.5, 50.24999994039248, -7.5)
+SketchLine_184.setName("SketchLine_77")
+SketchLine_184.result().setName("SketchLine_77")
+SketchLine_184.setAuxiliary(True)
+SketchConstraintCoincidence_272 = Sketch_17.setCoincident(SketchArc_39.startPoint(), SketchLine_184.endPoint())
+SketchConstraintCoincidence_272.setName("SketchConstraintCoincidence_103")
+SketchConstraintCoincidence_273 = Sketch_17.setCoincident(SketchArc_39.endPoint(), SketchLine_171.startPoint())
+SketchConstraintCoincidence_273.setName("SketchConstraintCoincidence_104")
+SketchConstraintTangent_19 = Sketch_17.setTangent(SketchArc_39.results()[1], SketchLine_184.result())
+SketchConstraintTangent_20 = Sketch_17.setTangent(SketchArc_39.results()[1], SketchLine_171.result())
+SketchConstraintCoincidence_274 = Sketch_17.setCoincident(SketchLine_177.startPoint(), SketchLine_184.startPoint())
+SketchConstraintCoincidence_274.setName("SketchConstraintCoincidence_105")
+SketchConstraintCoincidence_275 = Sketch_17.setCoincident(SketchLine_181.endPoint(), SketchLine_171.endPoint())
+SketchConstraintCoincidence_275.setName("SketchConstraintCoincidence_106")
+SketchConstraintCoincidence_276 = Sketch_17.setCoincident(SketchLine_184.endPoint(), SketchLine_177.result())
+SketchConstraintCoincidence_276.setName("SketchConstraintCoincidence_107")
+SketchConstraintCoincidence_277 = Sketch_17.setCoincident(SketchLine_171.startPoint(), SketchLine_181.result())
+SketchConstraintCoincidence_277.setName("SketchConstraintCoincidence_108")
+SketchArc_40 = Sketch_17.addArc(31.25000000000003, -7.250000000000001, 31, -7.249999999972618, 31.25000000003855, -7.5, False)
+SketchConstraintCoincidence_278 = Sketch_17.setCoincident(SketchArc_40.startPoint(), SketchLine_172.endPoint())
+SketchConstraintCoincidence_278.setName("SketchConstraintCoincidence_109")
+SketchConstraintCoincidence_279 = Sketch_17.setCoincident(SketchArc_40.endPoint(), SketchLine_173.startPoint())
+SketchConstraintCoincidence_279.setName("SketchConstraintCoincidence_110")
+SketchConstraintTangent_21 = Sketch_17.setTangent(SketchArc_40.results()[1], SketchLine_173.result())
+SketchConstraintTangent_22 = Sketch_17.setTangent(SketchArc_40.results()[1], SketchLine_172.result())
+SketchConstraintCoincidence_280 = Sketch_17.setCoincident(SketchLine_184.endPoint(), SketchLine_173.endPoint())
+SketchConstraintCoincidence_280.setName("SketchConstraintCoincidence_111")
+SketchConstraintCoincidence_281 = Sketch_17.setCoincident(SketchLine_183.startPoint(), SketchLine_172.startPoint())
+SketchConstraintCoincidence_281.setName("SketchConstraintCoincidence_112")
+SketchConstraintCoincidence_282 = Sketch_17.setCoincident(SketchLine_173.startPoint(), SketchLine_184.result())
+SketchConstraintCoincidence_282.setName("SketchConstraintCoincidence_113")
+SketchConstraintCoincidence_283 = Sketch_17.setCoincident(SketchLine_172.endPoint(), SketchLine_183.result())
+SketchConstraintCoincidence_283.setName("SketchConstraintCoincidence_114")
+SketchConstraintRadius_16 = Sketch_17.setRadius(SketchArc_37.results()[1], 0.75)
+SketchConstraintRadius_17 = Sketch_17.setRadius(SketchArc_39.results()[1], 0.75)
+SketchConstraintRadius_18 = Sketch_17.setRadius(SketchArc_38.results()[1], 0.25)
+SketchConstraintRadius_19 = Sketch_17.setRadius(SketchArc_40.results()[1], 0.25)
+model.do()
+ExtrusionCut_15 = model.addExtrusionCut(Part_2_doc, [model.selection("COMPOUND", "Sketch_7")], model.selection(), 0, 20, [model.selection("SOLID", "ExtrusionFuse_1_1")])
+Sketch_18 = model.addSketch(Part_2_doc, model.selection("FACE", "ExtrusionCut_6_1/Modfied_17"))
+SketchPoint_36 = Sketch_18.addPoint(53.99994409538203, -1.615587133892632e-027)
+SketchPoint_37 = Sketch_18.addPoint(53.99994409538203, -1.615587133892632e-027)
+SketchConstraintRigid_20 = Sketch_18.setFixed(SketchPoint_37.result())
+SketchConstraintRigid_20.setName("SketchConstraintRigid_16")
+SketchConstraintCoincidence_284 = Sketch_18.setCoincident(SketchPoint_36.coordinates(), SketchPoint_37.result())
+SketchConstraintCoincidence_284.setName("SketchConstraintCoincidence_115")
+SketchPoint_38 = Sketch_18.addPoint(54, 12)
+SketchLine_185 = Sketch_18.addLine(54, 12, 53.99994409538203, -1.615587133892632e-027)
+SketchLine_185.setName("SketchLine_81")
+SketchLine_185.result().setName("SketchLine_81")
+SketchLine_185.setAuxiliary(True)
+SketchConstraintCoincidence_285 = Sketch_18.setCoincident(SketchPoint_38.coordinates(), SketchLine_185.startPoint())
+SketchConstraintCoincidence_285.setName("SketchConstraintCoincidence_116")
+SketchConstraintCoincidence_286 = Sketch_18.setCoincident(SketchPoint_36.coordinates(), SketchLine_185.endPoint())
+SketchConstraintCoincidence_286.setName("SketchConstraintCoincidence_117")
+SketchConstraintCoincidence_287 = Sketch_18.setCoincident(SketchPoint_37.coordinates(), SketchLine_185.endPoint())
+SketchConstraintCoincidence_287.setName("SketchConstraintCoincidence_118")
+SketchPoint_39 = Sketch_18.addPoint(53.99999534128184, 11.00000000001085)
+SketchConstraintCoincidence_288 = Sketch_18.setCoincident(SketchPoint_39.coordinates(), SketchLine_185.result())
+SketchConstraintCoincidence_288.setName("SketchConstraintCoincidence_119")
+SketchPoint_40 = Sketch_18.addPoint(53.99994875410019, 0.9999999999891482)
+SketchConstraintCoincidence_289 = Sketch_18.setCoincident(SketchPoint_40.coordinates(), SketchLine_185.result())
+SketchConstraintCoincidence_289.setName("SketchConstraintCoincidence_120")
+SketchConstraintDistance_31 = Sketch_18.setDistance(SketchPoint_36.coordinates(), SketchPoint_40.coordinates(), 1)
+SketchConstraintDistance_32 = Sketch_18.setDistance(SketchPoint_38.coordinates(), SketchPoint_39.coordinates(), 1)
+SketchPoint_41 = Sketch_18.addPoint(54, 12)
+SketchConstraintCoincidence_290 = Sketch_18.setCoincident(SketchPoint_38.coordinates(), SketchPoint_41.coordinates())
+SketchConstraintCoincidence_290.setName("SketchConstraintCoincidence_121")
+SketchConstraintRigid_21 = Sketch_18.setFixed(SketchPoint_41.result())
+SketchConstraintRigid_21.setName("SketchConstraintRigid_17")
+SketchLine_186 = Sketch_18.addLine(53.99999534128184, 11.00000000001085, 43.53696016024325, 11.00000000001085)
+SketchLine_186.setName("SketchLine_82")
+SketchLine_186.result().setName("SketchLine_82")
+SketchConstraintCoincidence_291 = Sketch_18.setCoincident(SketchPoint_39.coordinates(), SketchLine_186.startPoint())
+SketchConstraintCoincidence_291.setName("SketchConstraintCoincidence_122")
+SketchLine_187 = Sketch_18.addLine(43.53696016024325, 11.00000000001085, 43.56530536601203, 13.47539228785809)
+SketchLine_187.setName("SketchLine_83")
+SketchLine_187.result().setName("SketchLine_83")
+SketchConstraintCoincidence_292 = Sketch_18.setCoincident(SketchLine_186.endPoint(), SketchLine_187.startPoint())
+SketchConstraintCoincidence_292.setName("SketchConstraintCoincidence_123")
+SketchLine_188 = Sketch_18.addLine(43.56530536601203, 13.47539228785809, 63.09515214070713, 13.47539228785809)
+SketchLine_188.setName("SketchLine_84")
+SketchLine_188.result().setName("SketchLine_84")
+SketchConstraintCoincidence_293 = Sketch_18.setCoincident(SketchLine_187.endPoint(), SketchLine_188.startPoint())
+SketchConstraintCoincidence_293.setName("SketchConstraintCoincidence_124")
+SketchLine_189 = Sketch_18.addLine(63.09515214070713, 13.47539228785809, 63.12349734647592, -1.774328415749978)
+SketchLine_189.setName("SketchLine_85")
+SketchLine_189.result().setName("SketchLine_85")
+SketchConstraintCoincidence_294 = Sketch_18.setCoincident(SketchLine_188.endPoint(), SketchLine_189.startPoint())
+SketchConstraintCoincidence_294.setName("SketchConstraintCoincidence_125")
+SketchLine_190 = Sketch_18.addLine(63.12349734647592, -1.774328415749978, 43.82041221793113, -1.802673621518767)
+SketchLine_190.setName("SketchLine_86")
+SketchLine_190.result().setName("SketchLine_86")
+SketchConstraintCoincidence_295 = Sketch_18.setCoincident(SketchLine_189.endPoint(), SketchLine_190.startPoint())
+SketchConstraintCoincidence_295.setName("SketchConstraintCoincidence_126")
+SketchLine_191 = Sketch_18.addLine(43.82041221793113, -1.802673621518767, 43.79206701216234, 0.9999999999891482)
+SketchLine_191.setName("SketchLine_87")
+SketchLine_191.result().setName("SketchLine_87")
+SketchConstraintCoincidence_296 = Sketch_18.setCoincident(SketchLine_190.endPoint(), SketchLine_191.startPoint())
+SketchConstraintCoincidence_296.setName("SketchConstraintCoincidence_127")
+SketchLine_192 = Sketch_18.addLine(53.99994875410019, 0.9999999999891482, 43.79206701216234, 0.9999999999891482)
+SketchLine_192.setName("SketchLine_88")
+SketchLine_192.result().setName("SketchLine_88")
+SketchConstraintCoincidence_297 = Sketch_18.setCoincident(SketchPoint_40.coordinates(), SketchLine_192.startPoint())
+SketchConstraintCoincidence_297.setName("SketchConstraintCoincidence_128")
+SketchConstraintHorizontal_37 = Sketch_18.setHorizontal(SketchLine_192.result())
+SketchConstraintHorizontal_37.setName("SketchConstraintHorizontal_16")
+SketchConstraintHorizontal_38 = Sketch_18.setHorizontal(SketchLine_186.result())
+SketchConstraintHorizontal_38.setName("SketchConstraintHorizontal_17")
+SketchConstraintCoincidence_298 = Sketch_18.setCoincident(SketchLine_191.endPoint(), SketchLine_192.endPoint())
+SketchConstraintCoincidence_298.setName("SketchConstraintCoincidence_129")
+SketchArc_41 = Sketch_18.addArc(53.99995774377268, 6.000000000066637, 53.99999534128184, 11.00000000001085, 53.99994875410019, 0.9999999999891482, True)
+SketchConstraintCoincidence_299 = Sketch_18.setCoincident(SketchPoint_39.coordinates(), SketchArc_41.startPoint())
+SketchConstraintCoincidence_299.setName("SketchConstraintCoincidence_130")
+SketchConstraintCoincidence_300 = Sketch_18.setCoincident(SketchLine_186.startPoint(), SketchArc_41.startPoint())
+SketchConstraintCoincidence_300.setName("SketchConstraintCoincidence_131")
+SketchConstraintCoincidence_301 = Sketch_18.setCoincident(SketchPoint_40.coordinates(), SketchArc_41.endPoint())
+SketchConstraintCoincidence_301.setName("SketchConstraintCoincidence_132")
+SketchConstraintCoincidence_302 = Sketch_18.setCoincident(SketchLine_192.startPoint(), SketchArc_41.endPoint())
+SketchConstraintCoincidence_302.setName("SketchConstraintCoincidence_133")
+SketchConstraintRadius_20 = Sketch_18.setRadius(SketchArc_41.results()[1], 5)
+SketchLine_193 = Sketch_18.addLine(43.50261344273609, 8.249999999999998, 43.50261344273609, 3.749999999999998)
+SketchLine_193.setName("SketchLine_90")
+SketchLine_193.result().setName("SketchLine_90")
+SketchConstraintVertical_33 = Sketch_18.setVertical(SketchLine_193.result())
+SketchConstraintLength_31 = Sketch_18.setLength(SketchLine_193.result(), 4.5)
+SketchConstraintLength_31.setName("SketchConstraintLength_15")
+SketchPoint_42 = Sketch_18.addPoint(43.50261344273609, 5.999999999999998)
+SketchConstraintMiddle_13 = Sketch_18.setMiddlePoint(SketchPoint_42.coordinates(), SketchLine_193.result())
+SketchPoint_43 = Sketch_18.addPoint(0, 6)
+SketchPoint_43.setAuxiliary(True)
+SketchLine_194 = Sketch_18.addLine(0, 0, 0, 12)
+SketchLine_194.setName("SketchLine_94")
+SketchLine_194.result().setName("SketchLine_94")
+SketchConstraintRigid_22 = Sketch_18.setFixed(SketchLine_194.result())
+SketchConstraintRigid_22.setName("SketchConstraintRigid_19")
+SketchConstraintCoincidence_303 = Sketch_18.setCoincident(SketchPoint_43.coordinates(), SketchLine_194.result())
+SketchConstraintCoincidence_303.setName("SketchConstraintCoincidence_139")
+SketchConstraintMiddle_14 = Sketch_18.setMiddlePoint(SketchLine_194.result(), SketchPoint_43.coordinates())
+SketchLine_195 = Sketch_18.addLine(0, 6, 68.8619738308997, 6)
+SketchLine_195.setName("SketchLine_95")
+SketchLine_195.result().setName("SketchLine_95")
+SketchLine_195.setAuxiliary(True)
+SketchConstraintCoincidence_304 = Sketch_18.setCoincident(SketchPoint_43.coordinates(), SketchLine_195.startPoint())
+SketchConstraintCoincidence_304.setName("SketchConstraintCoincidence_140")
+SketchConstraintHorizontal_39 = Sketch_18.setHorizontal(SketchLine_195.result())
+SketchConstraintHorizontal_39.setName("SketchConstraintHorizontal_20")
+SketchPoint_44 = Sketch_18.addPoint(48.00130672136804, 6)
+SketchConstraintCoincidence_305 = Sketch_18.setCoincident(SketchPoint_44.coordinates(), SketchLine_195.result())
+SketchConstraintCoincidence_305.setName("SketchConstraintCoincidence_146")
+SketchLine_196 = Sketch_18.addLine(43.50261344273609, 8.249999999999998, 51.26978940411676, 8.249999999999998)
+SketchLine_196.setName("SketchLine_92")
+SketchLine_196.result().setName("SketchLine_92")
+SketchConstraintCoincidence_306 = Sketch_18.setCoincident(SketchLine_193.startPoint(), SketchLine_196.startPoint())
+SketchConstraintCoincidence_306.setName("SketchConstraintCoincidence_135")
+SketchLine_197 = Sketch_18.addLine(51.26978940411676, 8.249999999999998, 51.26978940411676, 3.749999999999998)
+SketchLine_197.setName("SketchLine_97")
+SketchLine_197.result().setName("SketchLine_97")
+SketchConstraintCoincidence_307 = Sketch_18.setCoincident(SketchLine_196.endPoint(), SketchLine_197.startPoint())
+SketchConstraintCoincidence_307.setName("SketchConstraintCoincidence_136")
+SketchLine_198 = Sketch_18.addLine(51.26978940411676, 3.749999999999998, 43.50261344273609, 3.749999999999998)
+SketchLine_198.setName("SketchLine_98")
+SketchLine_198.result().setName("SketchLine_98")
+SketchConstraintCoincidence_308 = Sketch_18.setCoincident(SketchLine_197.endPoint(), SketchLine_198.startPoint())
+SketchConstraintCoincidence_308.setName("SketchConstraintCoincidence_137")
+SketchConstraintCoincidence_309 = Sketch_18.setCoincident(SketchLine_193.endPoint(), SketchLine_198.endPoint())
+SketchConstraintCoincidence_309.setName("SketchConstraintCoincidence_138")
+SketchConstraintHorizontal_40 = Sketch_18.setHorizontal(SketchLine_198.result())
+SketchConstraintHorizontal_41 = Sketch_18.setHorizontal(SketchLine_196.result())
+SketchConstraintVertical_34 = Sketch_18.setVertical(SketchLine_197.result())
+SketchLine_199 = Sketch_18.addLine(43.50261344273609, 3.749999999999998, 51.26978940411676, 8.249999999999998)
+SketchLine_199.setAuxiliary(True)
+SketchConstraintCoincidence_310 = Sketch_18.setCoincident(SketchLine_193.endPoint(), SketchLine_199.startPoint())
+SketchConstraintCoincidence_310.setName("SketchConstraintCoincidence_141")
+SketchConstraintCoincidence_311 = Sketch_18.setCoincident(SketchLine_198.endPoint(), SketchLine_199.startPoint())
+SketchConstraintCoincidence_311.setName("SketchConstraintCoincidence_142")
+SketchConstraintCoincidence_312 = Sketch_18.setCoincident(SketchLine_197.startPoint(), SketchLine_199.endPoint())
+SketchConstraintCoincidence_312.setName("SketchConstraintCoincidence_143")
+SketchPoint_45 = Sketch_18.addPoint(47.38620142342643, 5.999999999999998)
+SketchPoint_45.setAuxiliary(True)
+SketchConstraintCoincidence_313 = Sketch_18.setCoincident(SketchPoint_45.coordinates(), SketchLine_199.result())
+SketchConstraintCoincidence_313.setName("SketchConstraintCoincidence_144")
+SketchConstraintMiddle_15 = Sketch_18.setMiddlePoint(SketchPoint_45.coordinates(), SketchLine_199.result())
+SketchConstraintCoincidence_314 = Sketch_18.setCoincident(SketchPoint_45.coordinates(), SketchLine_195.result())
+SketchConstraintCoincidence_314.setName("SketchConstraintCoincidence_145")
+model.do()
+ExtrusionCut_16 = model.addExtrusionCut(Part_2_doc, [model.selection("COMPOUND", "Sketch_8")], model.selection(), 10, 0, [model.selection("SOLID", "ExtrusionCut_6_1")])
+Sketch_19 = model.addSketch(Part_2_doc, model.selection("FACE", "ExtrusionCut_7_1/Modfied_56"))
+SketchLine_200 = Sketch_19.addLine(21.00014787857639, 4.163450069699051, 21.00014787857639, 0)
+SketchLine_200.setName("SketchLine_107")
+SketchLine_200.result().setName("SketchLine_107")
+SketchLine_201 = Sketch_19.addLine(29, 5, 21.00014787857639, 5)
+SketchLine_201.setName("SketchLine_96")
+SketchLine_201.result().setName("SketchLine_96")
+SketchLine_201.setAuxiliary(True)
+SketchArc_42 = Sketch_19.addArc(25.00007393928819, 8.000098583186649, 21.53790262696343, 4.392693725936027, 28.46224525161297, 4.392693725936026, False)
+SketchArc_42.setName("SketchArc_22")
+SketchArc_42.result().setName("SketchArc_22")
+SketchArc_42.results()[1].setName("SketchArc_22_2")
+SketchLine_202 = Sketch_19.addLine(21.00014787857639, 0, 29, 0)
+SketchLine_202.setName("SketchLine_100")
+SketchLine_202.result().setName("SketchLine_100")
+SketchLine_203 = Sketch_19.addLine(29, 0, 29, 4.163450069699049)
+SketchLine_203.setName("SketchLine_108")
+SketchLine_203.result().setName("SketchLine_108")
+SketchLine_204 = Sketch_19.addLine(29, 0, 29, 5)
+SketchLine_204.setName("SketchLine_101")
+SketchLine_204.result().setName("SketchLine_101")
+SketchLine_204.setAuxiliary(True)
+SketchConstraintCoincidence_315 = Sketch_19.setCoincident(SketchLine_204.endPoint(), SketchLine_201.startPoint())
+SketchConstraintCoincidence_315.setName("SketchConstraintCoincidence_147")
+SketchLine_205 = Sketch_19.addLine(21.00014787857639, 5, 21.00014787857639, 0)
+SketchLine_205.setAuxiliary(True)
+SketchConstraintCoincidence_316 = Sketch_19.setCoincident(SketchLine_201.endPoint(), SketchLine_205.startPoint())
+SketchConstraintCoincidence_316.setName("SketchConstraintCoincidence_148")
+SketchConstraintCoincidence_317 = Sketch_19.setCoincident(SketchLine_205.endPoint(), SketchLine_202.startPoint())
+SketchConstraintCoincidence_317.setName("SketchConstraintCoincidence_149")
+SketchConstraintCoincidence_318 = Sketch_19.setCoincident(SketchLine_202.endPoint(), SketchLine_204.startPoint())
+SketchConstraintCoincidence_318.setName("SketchConstraintCoincidence_150")
+SketchConstraintHorizontal_42 = Sketch_19.setHorizontal(SketchLine_201.result())
+SketchConstraintHorizontal_42.setName("SketchConstraintHorizontal_21")
+SketchConstraintVertical_35 = Sketch_19.setVertical(SketchLine_205.result())
+SketchConstraintHorizontal_43 = Sketch_19.setHorizontal(SketchLine_202.result())
+SketchConstraintHorizontal_43.setName("SketchConstraintHorizontal_22")
+SketchConstraintVertical_36 = Sketch_19.setVertical(SketchLine_204.result())
+SketchPoint_46 = Sketch_19.addPoint(21.00014787857639, 7.5)
+SketchConstraintCoincidence_319 = Sketch_19.setCoincident(SketchLine_205.result(), SketchPoint_46.coordinates())
+SketchConstraintCoincidence_319.setName("SketchConstraintCoincidence_151")
+SketchConstraintRigid_23 = Sketch_19.setFixed(SketchPoint_46.result())
+SketchConstraintRigid_23.setName("SketchConstraintRigid_18")
+SketchPoint_47 = Sketch_19.addPoint(29, 7.5)
+SketchConstraintCoincidence_320 = Sketch_19.setCoincident(SketchLine_204.result(), SketchPoint_47.coordinates())
+SketchConstraintCoincidence_320.setName("SketchConstraintCoincidence_152")
+SketchConstraintRigid_24 = Sketch_19.setFixed(SketchPoint_47.result())
+SketchConstraintRigid_24.setName("SketchConstraintRigid_20")
+SketchConstraintLength_32 = Sketch_19.setLength(SketchLine_205.result(), 5)
+SketchConstraintLength_32.setName("SketchConstraintLength_16")
+SketchLine_206 = Sketch_19.addLine(0, 0, 45.49999999999999, 0)
+SketchLine_206.setName("SketchLine_102")
+SketchLine_206.result().setName("SketchLine_102")
+SketchConstraintCoincidence_321 = Sketch_19.setCoincident(SketchLine_205.endPoint(), SketchLine_206.result())
+SketchConstraintCoincidence_321.setName("SketchConstraintCoincidence_153")
+SketchConstraintRigid_25 = Sketch_19.setFixed(SketchLine_206.result())
+SketchConstraintRigid_25.setName("SketchConstraintRigid_21")
+SketchArc_43 = Sketch_19.addArc(25.00007393928819, 8.000098583186649, 21.00014787857639, 5, 29, 5, False)
+SketchArc_43.setName("SketchArc_19")
+SketchArc_43.result().setName("SketchArc_19")
+SketchArc_43.results()[1].setName("SketchArc_19_2")
+SketchArc_43.setAuxiliary(True)
+SketchConstraintCoincidence_322 = Sketch_19.setCoincident(SketchLine_201.endPoint(), SketchArc_43.startPoint())
+SketchConstraintCoincidence_322.setName("SketchConstraintCoincidence_154")
+SketchConstraintCoincidence_323 = Sketch_19.setCoincident(SketchLine_205.startPoint(), SketchArc_43.startPoint())
+SketchConstraintCoincidence_323.setName("SketchConstraintCoincidence_155")
+SketchConstraintCoincidence_324 = Sketch_19.setCoincident(SketchLine_201.startPoint(), SketchArc_43.endPoint())
+SketchConstraintCoincidence_324.setName("SketchConstraintCoincidence_156")
+SketchConstraintCoincidence_325 = Sketch_19.setCoincident(SketchLine_204.endPoint(), SketchArc_43.endPoint())
+SketchConstraintCoincidence_325.setName("SketchConstraintCoincidence_157")
+SketchConstraintRadius_21 = Sketch_19.setRadius(SketchArc_43.results()[1], 5)
+SketchLine_207 = Sketch_19.addLine(1, 0, 1, 1.8)
+SketchLine_207.setName("SketchLine_103")
+SketchLine_207.result().setName("SketchLine_103")
+SketchConstraintCoincidence_326 = Sketch_19.setCoincident(SketchLine_207.startPoint(), SketchLine_206.result())
+SketchConstraintCoincidence_326.setName("SketchConstraintCoincidence_158")
+SketchLine_208 = Sketch_19.addLine(1, 1.8, 8, 3.389761862250954)
+SketchLine_208.setName("SketchLine_104")
+SketchLine_208.result().setName("SketchLine_104")
+SketchConstraintCoincidence_327 = Sketch_19.setCoincident(SketchLine_207.endPoint(), SketchLine_208.startPoint())
+SketchConstraintCoincidence_327.setName("SketchConstraintCoincidence_159")
+SketchLine_209 = Sketch_19.addLine(8, 3.389761862250954, 8, 0)
+SketchLine_209.setName("SketchLine_105")
+SketchLine_209.result().setName("SketchLine_105")
+SketchConstraintCoincidence_328 = Sketch_19.setCoincident(SketchLine_208.endPoint(), SketchLine_209.startPoint())
+SketchConstraintCoincidence_328.setName("SketchConstraintCoincidence_160")
+SketchLine_210 = Sketch_19.addLine(8, 0, 1, 0)
+SketchLine_210.setName("SketchLine_106")
+SketchLine_210.result().setName("SketchLine_106")
+SketchConstraintCoincidence_329 = Sketch_19.setCoincident(SketchLine_209.endPoint(), SketchLine_210.startPoint())
+SketchConstraintCoincidence_329.setName("SketchConstraintCoincidence_161")
+SketchConstraintCoincidence_330 = Sketch_19.setCoincident(SketchLine_207.startPoint(), SketchLine_210.endPoint())
+SketchConstraintCoincidence_330.setName("SketchConstraintCoincidence_162")
+SketchConstraintCoincidence_331 = Sketch_19.setCoincident(SketchLine_210.startPoint(), SketchLine_206.result())
+SketchConstraintCoincidence_331.setName("SketchConstraintCoincidence_163")
+SketchConstraintVertical_37 = Sketch_19.setVertical(SketchLine_209.result())
+SketchConstraintVertical_38 = Sketch_19.setVertical(SketchLine_207.result())
+SketchConstraintLength_33 = Sketch_19.setLength(SketchLine_210.result(), 7)
+SketchConstraintLength_33.setName("SketchConstraintLength_17")
+SketchConstraintDistance_33 = Sketch_19.setDistance(SketchLine_207.result(), SketchLine_206.startPoint(), 1)
+SketchConstraintLength_34 = Sketch_19.setLength(SketchLine_207.result(), 1.8)
+SketchConstraintLength_34.setName("SketchConstraintLength_18")
+SketchArc_44 = Sketch_19.addArc(21.3178882838101, 4.163450069699051, 21.53790262696343, 4.392693725936027, 21.00014787857639, 4.163450069699051, False)
+SketchArc_45 = Sketch_19.addArc(25.00007393928819, 8.000098583186649, 21.53790262696343, 4.392693725936027, 29, 5, False)
+SketchArc_45.setName("SketchArc_20")
+SketchArc_45.result().setName("SketchArc_20")
+SketchArc_45.results()[1].setName("SketchArc_20_2")
+SketchArc_45.setAuxiliary(True)
+SketchConstraintCoincidence_332 = Sketch_19.setCoincident(SketchArc_44.startPoint(), SketchArc_45.startPoint())
+SketchConstraintCoincidence_332.setName("SketchConstraintCoincidence_164")
+SketchConstraintCoincidence_333 = Sketch_19.setCoincident(SketchArc_44.endPoint(), SketchLine_200.startPoint())
+SketchConstraintCoincidence_333.setName("SketchConstraintCoincidence_165")
+SketchConstraintTangent_23 = Sketch_19.setTangent(SketchArc_44.results()[1], SketchLine_200.result())
+SketchConstraintTangent_24 = Sketch_19.setTangent(SketchArc_44.results()[1], SketchArc_45.results()[1])
+SketchConstraintCoincidence_334 = Sketch_19.setCoincident(SketchLine_205.endPoint(), SketchLine_200.endPoint())
+SketchConstraintCoincidence_334.setName("SketchConstraintCoincidence_166")
+SketchConstraintCoincidence_335 = Sketch_19.setCoincident(SketchArc_43.endPoint(), SketchArc_45.endPoint())
+SketchConstraintCoincidence_335.setName("SketchConstraintCoincidence_167")
+SketchConstraintTangent_25 = Sketch_19.setTangent(SketchArc_43.results()[1], SketchArc_45.results()[1])
+SketchConstraintCoincidence_336 = Sketch_19.setCoincident(SketchLine_200.startPoint(), SketchLine_205.result())
+SketchConstraintCoincidence_336.setName("SketchConstraintCoincidence_168")
+SketchConstraintCoincidence_337 = Sketch_19.setCoincident(SketchArc_45.startPoint(), SketchArc_43.results()[1])
+SketchConstraintCoincidence_337.setName("SketchConstraintCoincidence_169")
+SketchArc_46 = Sketch_19.addArc(28.68225959476629, 4.163450069699049, 29, 4.163450069699049, 28.46224525161297, 4.392693725936026, False)
+SketchConstraintCoincidence_338 = Sketch_19.setCoincident(SketchArc_46.startPoint(), SketchLine_203.endPoint())
+SketchConstraintCoincidence_338.setName("SketchConstraintCoincidence_170")
+SketchConstraintCoincidence_339 = Sketch_19.setCoincident(SketchArc_46.endPoint(), SketchArc_42.endPoint())
+SketchConstraintCoincidence_339.setName("SketchConstraintCoincidence_171")
+SketchConstraintTangent_26 = Sketch_19.setTangent(SketchArc_46.results()[1], SketchArc_42.results()[1])
+SketchConstraintTangent_27 = Sketch_19.setTangent(SketchArc_46.results()[1], SketchLine_203.result())
+SketchConstraintCoincidence_340 = Sketch_19.setCoincident(SketchArc_45.startPoint(), SketchArc_42.startPoint())
+SketchConstraintCoincidence_340.setName("SketchConstraintCoincidence_172")
+SketchConstraintCoincidence_341 = Sketch_19.setCoincident(SketchLine_204.startPoint(), SketchLine_203.startPoint())
+SketchConstraintCoincidence_341.setName("SketchConstraintCoincidence_173")
+SketchConstraintTangent_28 = Sketch_19.setTangent(SketchArc_45.results()[1], SketchArc_42.results()[1])
+SketchConstraintCoincidence_342 = Sketch_19.setCoincident(SketchArc_42.endPoint(), SketchArc_45.results()[1])
+SketchConstraintCoincidence_342.setName("SketchConstraintCoincidence_174")
+SketchConstraintCoincidence_343 = Sketch_19.setCoincident(SketchLine_203.endPoint(), SketchLine_204.result())
+SketchConstraintCoincidence_343.setName("SketchConstraintCoincidence_175")
+model.do()
+Plane_12 = model.addPlane(Part_2_doc, model.selection("FACE", "Plane_2"), 4, False)
+Plane_13 = model.addPlane(Part_2_doc, model.selection("FACE", "Plane_2"), 4, True)
+ExtrusionCut_17 = model.addExtrusionCut(Part_2_doc, [model.selection("COMPOUND", "Sketch_9")], model.selection(), model.selection("FACE", "Plane_5"), 0, model.selection("FACE", "Plane_4"), 0, [model.selection("SOLID", "ExtrusionCut_7_1")])
+Sketch_20 = model.addSketch(Part_2_doc, model.selection("FACE", "ExtrusionCut_8_1/Modfied_5"))
+SketchCircle_2 = Sketch_20.addCircle(12, 6, 1)
+SketchConstraintRadius_22 = Sketch_20.setRadius(SketchCircle_2.results()[1], 1)
+SketchPoint_48 = Sketch_20.addPoint(0, 6)
+SketchPoint_48.setAuxiliary(True)
+SketchLine_211 = Sketch_20.addLine(0, 0, 0, 12)
+SketchLine_211.setName("SketchLine_109")
+SketchLine_211.result().setName("SketchLine_109")
+SketchConstraintRigid_26 = Sketch_20.setFixed(SketchLine_211.result())
+SketchConstraintRigid_26.setName("SketchConstraintRigid_22")
+SketchConstraintCoincidence_344 = Sketch_20.setCoincident(SketchPoint_48.coordinates(), SketchLine_211.result())
+SketchConstraintCoincidence_344.setName("SketchConstraintCoincidence_176")
+SketchConstraintMiddle_16 = Sketch_20.setMiddlePoint(SketchLine_211.result(), SketchPoint_48.coordinates())
+SketchLine_212 = Sketch_20.addLine(0, 6, 17.31036191565843, 6)
+SketchLine_212.setName("SketchLine_110")
+SketchLine_212.result().setName("SketchLine_110")
+SketchLine_212.setAuxiliary(True)
+SketchConstraintCoincidence_345 = Sketch_20.setCoincident(SketchPoint_48.coordinates(), SketchLine_212.startPoint())
+SketchConstraintCoincidence_345.setName("SketchConstraintCoincidence_177")
+SketchConstraintHorizontal_44 = Sketch_20.setHorizontal(SketchLine_212.result())
+SketchConstraintHorizontal_44.setName("SketchConstraintHorizontal_23")
+SketchConstraintCoincidence_346 = Sketch_20.setCoincident(SketchCircle_2.center(), SketchLine_212.result())
+SketchConstraintCoincidence_346.setName("SketchConstraintCoincidence_178")
+SketchConstraintDistance_34 = Sketch_20.setDistance(SketchLine_211.result(), SketchCircle_2.center(), 12)
+model.do()
+ExtrusionCut_18 = model.addExtrusionCut(Part_2_doc, [model.selection("WIRE", "Sketch_10/Wire-SketchCircle_1_2f")], model.selection(), 0, 0.75, [model.selection("SOLID", "ExtrusionCut_8_1")])
+model.do()
+Rotation_1 = model.addRotation(partSet, [model.selection("COMPOUND", "Part_2/")], model.selection("EDGE", "Part_1/ExtrusionCut_9_1/Modfied_1&ExtrusionCut_7_1/Modfied_57"), 180)
+Placement_1 = model.addPlacement(partSet, [model.selection("COMPOUND", "Rotation_1/")], model.selection("FACE", "Rotation_1/ExtrusionCut_5_1/Modfied_1"), model.selection("FACE", "Part_1/ExtrusionCut_5_1/Modfied_1"), False, True)
+Rotation_2 = model.addRotation(partSet, [model.selection("COMPOUND", "Placement_1/")], model.selection("EDGE", "Part_1/ExtrusionCut_5_1/Modfied_8&ExtrusionCut_8_1/Modfied_3"), 7)
+Rotation_2.result().setColor(255, 85, 0)
model.end()
from GeomAPI import GeomAPI_Shape
-model.testNbResults(ExtrusionCut_9, 1)
-model.testNbSubResults(ExtrusionCut_9, [0])
-model.testNbSubShapes(ExtrusionCut_9, GeomAPI_Shape.SOLID, [1])
-model.testNbSubShapes(ExtrusionCut_9, GeomAPI_Shape.FACE, [172])
-model.testNbSubShapes(ExtrusionCut_9, GeomAPI_Shape.EDGE, [804])
-model.testNbSubShapes(ExtrusionCut_9, GeomAPI_Shape.VERTEX, [1608])
-model.testResultsVolumes(ExtrusionCut_9, [1876.328652945095427639898844063])
+model.testNbResults(Part_1, 1)
+model.testNbSubResults(Part_1, [0])
+model.testNbSubShapes(Part_1, GeomAPI_Shape.SOLID, [1])
+model.testNbSubShapes(Part_1, GeomAPI_Shape.FACE, [172])
+model.testNbSubShapes(Part_1, GeomAPI_Shape.EDGE, [804])
+model.testNbSubShapes(Part_1, GeomAPI_Shape.VERTEX, [1608])
+model.testResultsVolumes(Part_1, [1876.328652945015164732467383146])
+
+model.testNbResults(Rotation_2, 1)
+model.testNbSubResults(Rotation_2, [0])
+model.testNbSubShapes(Rotation_2, GeomAPI_Shape.SOLID, [1])
+model.testNbSubShapes(Rotation_2, GeomAPI_Shape.FACE, [172])
+model.testNbSubShapes(Rotation_2, GeomAPI_Shape.EDGE, [804])
+model.testNbSubShapes(Rotation_2, GeomAPI_Shape.VERTEX, [1608])
+model.testResultsVolumes(Rotation_2, [1876.328652945015846853493712842])
-assert(model.checkPythonDump)
+assert(model.checkPythonDump())
model.testNbSubShapes(Boolean_1, GeomAPI_Shape.FACE, [35])
model.testNbSubShapes(Boolean_1, GeomAPI_Shape.EDGE, [162])
model.testNbSubShapes(Boolean_1, GeomAPI_Shape.VERTEX, [324])
-model.testResultsVolumes(Boolean_1, [2053931.555419394280761480331420898])
+model.testResultsVolumes(Boolean_1, [2053931.913933836854994297027587891])
assert(model.checkPythonDump())
mouseClick(waitForObject(":OpenParts*_AppElements_ViewPort"), annotaion_point[0], annotaion_point[1], 0, Qt.LeftButton)
waitFor("object.exists(':Distance.First object_QLineEdit')", 20000)
- test.compare(str(findObject(":Distance.First object_QLineEdit").text), "SketchPoint_1/PointCoordindates")
+ test.compare(str(findObject(":Distance.First object_QLineEdit").text), "SketchPoint_1/PointCoordinates")
waitFor("object.exists(':Distance.Second object_QLineEdit')", 20000)
test.compare(str(findObject(":Distance.Second object_QLineEdit").text), "SketchLine_1")
waitFor("object.exists(':Distance.ConstraintValue_ModuleBase_ParamSpinBox')", 20000)