| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | #include <BRep_Builder.hxx> |
| | #include <Precision.hxx> |
| | #include <TopoDS_Compound.hxx> |
| |
|
| |
|
| | #include <Base/Console.h> |
| | #include <Base/Placement.h> |
| |
|
| | #include "FeatureArea.h" |
| | #include "FeatureAreaPy.h" |
| |
|
| |
|
| | FC_LOG_LEVEL_INIT("Path.Area", true, true) |
| |
|
| | using namespace Path; |
| |
|
| | PROPERTY_SOURCE(Path::FeatureArea, Part::Feature) |
| |
|
| | PARAM_ENUM_STRING_DECLARE(static const char* Enums, AREA_PARAMS_ALL) |
| |
|
| | FeatureArea::FeatureArea() |
| | : myInited(false) |
| | { |
| | ADD_PROPERTY(Sources, (nullptr)); |
| | ADD_PROPERTY(WorkPlane, (TopoDS_Shape())); |
| |
|
| | PARAM_PROP_ADD("Area", AREA_PARAMS_OPCODE); |
| | PARAM_PROP_ADD("Area", AREA_PARAMS_BASE); |
| | PARAM_PROP_ADD("Offset", AREA_PARAMS_OFFSET); |
| | PARAM_PROP_ADD("Offset", AREA_PARAMS_OFFSET_CONF); |
| | PARAM_PROP_ADD("Pocket", AREA_PARAMS_POCKET); |
| | PARAM_PROP_ADD("Pocket", AREA_PARAMS_POCKET_CONF); |
| | PARAM_PROP_ADD("Section", AREA_PARAMS_SECTION); |
| | PARAM_PROP_ADD("libarea", AREA_PARAMS_CAREA); |
| |
|
| | PARAM_PROP_SET_ENUM(Enums, AREA_PARAMS_ALL); |
| | PocketMode.setValue((long)0); |
| | } |
| |
|
| | FeatureArea::~FeatureArea() |
| | {} |
| |
|
| | Area& FeatureArea::getArea() |
| | { |
| | if (!myInited) { |
| | execute(); |
| | } |
| | return myArea; |
| | } |
| |
|
| | App::DocumentObjectExecReturn* FeatureArea::execute() |
| | { |
| | myInited = true; |
| |
|
| | std::vector<App::DocumentObject*> links = Sources.getValues(); |
| | if (links.empty()) { |
| | return new App::DocumentObjectExecReturn("No shapes linked"); |
| | } |
| |
|
| | for (std::vector<App::DocumentObject*>::iterator it = links.begin(); it != links.end(); ++it) { |
| | if (!(*it && (*it)->isDerivedFrom<Part::Feature>())) { |
| | return new App::DocumentObjectExecReturn( |
| | "Linked object is not a Part object (has no Shape)." |
| | ); |
| | } |
| | TopoDS_Shape shape = static_cast<Part::Feature*>(*it)->Shape.getShape().getShape(); |
| | if (shape.IsNull()) { |
| | return new App::DocumentObjectExecReturn("Linked shape object is empty"); |
| | } |
| | } |
| |
|
| | FC_TIME_INIT(t); |
| |
|
| | AreaParams params; |
| |
|
| | #define AREA_PROP_GET(_param) params.PARAM_FNAME(_param) = PARAM_FNAME(_param).getValue(); |
| | PARAM_FOREACH(AREA_PROP_GET, AREA_PARAMS_CONF) |
| |
|
| | myArea.clean(true); |
| | myArea.setParams(params); |
| |
|
| | TopoDS_Shape workPlane = WorkPlane.getShape().getShape(); |
| | myArea.setPlane(workPlane); |
| |
|
| | for (std::vector<App::DocumentObject*>::iterator it = links.begin(); it != links.end(); ++it) { |
| | myArea.add( |
| | static_cast<Part::Feature*>(*it)->Shape.getShape().getShape(), |
| | PARAM_PROP_ARGS(AREA_PARAMS_OPCODE) |
| | ); |
| | } |
| |
|
| | myShapes.clear(); |
| | if (myArea.getSectionCount() == 0) { |
| | myShapes.push_back(myArea.getShape(-1)); |
| | } |
| | else { |
| | myShapes.reserve(myArea.getSectionCount()); |
| | for (int i = 0; i < (int)myArea.getSectionCount(); ++i) { |
| | myShapes.push_back(myArea.getShape(i)); |
| | } |
| | } |
| |
|
| | bool hasShape = false; |
| | if (myShapes.empty()) { |
| | Shape.setValue(TopoDS_Shape()); |
| | } |
| | else { |
| | |
| | |
| | BRep_Builder builder; |
| | TopoDS_Compound compound; |
| | builder.MakeCompound(compound); |
| | for (auto& shape : myShapes) { |
| | if (shape.IsNull()) { |
| | continue; |
| | } |
| | hasShape = true; |
| | builder.Add(compound, shape); |
| | } |
| | Shape.setValue(compound); |
| | } |
| |
|
| | FC_TIME_LOG(t, "feature execute"); |
| |
|
| | if (!hasShape) { |
| | return new App::DocumentObjectExecReturn("no output shape"); |
| | } |
| |
|
| | return DocumentObject::StdReturn; |
| | } |
| |
|
| | const std::vector<TopoDS_Shape>& FeatureArea::getShapes() |
| | { |
| | getArea(); |
| | return myShapes; |
| | } |
| |
|
| | short FeatureArea::mustExecute() const |
| | { |
| | if (myInited && !myArea.isBuilt()) { |
| | return 1; |
| | } |
| | return Part::Feature::mustExecute(); |
| | } |
| |
|
| | PyObject* FeatureArea::getPyObject() |
| | { |
| | if (PythonObject.is(Py::_None())) { |
| | |
| | PythonObject = Py::Object(new FeatureAreaPy(this), true); |
| | } |
| | return Py::new_reference_to(PythonObject); |
| | } |
| |
|
| |
|
| | |
| | |
| | PROPERTY_SOURCE(Path::FeatureAreaView, Part::Feature) |
| |
|
| | FeatureAreaView::FeatureAreaView() |
| | { |
| | ADD_PROPERTY(Source, (nullptr)); |
| | ADD_PROPERTY_TYPE( |
| | SectionIndex, |
| | (0), |
| | "Section", |
| | App::Prop_None, |
| | "The start index of the section to show, negative value for reverse index from bottom" |
| | ); |
| | ADD_PROPERTY_TYPE( |
| | SectionCount, |
| | (1), |
| | "Section", |
| | App::Prop_None, |
| | "Number of sections to show, 0 to show all section starting from SectionIndex" |
| | ); |
| | } |
| |
|
| | std::list<TopoDS_Shape> FeatureAreaView::getShapes() |
| | { |
| | std::list<TopoDS_Shape> shapes; |
| | App::DocumentObject* pObj = Source.getValue(); |
| | if (!pObj) { |
| | return shapes; |
| | } |
| | if (!pObj->isDerivedFrom<FeatureArea>()) { |
| | return shapes; |
| | } |
| |
|
| | auto all_shapes = static_cast<FeatureArea*>(pObj)->getShapes(); |
| |
|
| | if (all_shapes.empty()) { |
| | return shapes; |
| | } |
| |
|
| | int index = SectionIndex.getValue(), count = SectionCount.getValue(); |
| | if (index < 0) { |
| | index += ((int)all_shapes.size()); |
| | if (index < 0) { |
| | return shapes; |
| | } |
| | if (count <= 0 || index + 1 - count < 0) { |
| | count = index + 1; |
| | index = 0; |
| | } |
| | else { |
| | index -= count - 1; |
| | } |
| | } |
| | else if (index >= (int)all_shapes.size()) { |
| | return shapes; |
| | } |
| |
|
| | if (count <= 0) { |
| | count = all_shapes.size(); |
| | } |
| | count += index; |
| | if (count > (int)all_shapes.size()) { |
| | count = all_shapes.size(); |
| | } |
| | for (int i = index; i < count; ++i) { |
| | shapes.push_back(all_shapes[i]); |
| | } |
| | return shapes; |
| | } |
| |
|
| | App::DocumentObjectExecReturn* FeatureAreaView::execute() |
| | { |
| | App::DocumentObject* pObj = Source.getValue(); |
| | if (!pObj) { |
| | return new App::DocumentObjectExecReturn("No shape linked"); |
| | } |
| |
|
| | if (!pObj->isDerivedFrom<FeatureArea>()) { |
| | return new App::DocumentObjectExecReturn("Linked object is not a FeatureArea"); |
| | } |
| |
|
| | bool hasShape = false; |
| | std::list<TopoDS_Shape> shapes = getShapes(); |
| | if (shapes.empty()) { |
| | Shape.setValue(TopoDS_Shape()); |
| | } |
| | else { |
| | BRep_Builder builder; |
| | TopoDS_Compound compound; |
| | builder.MakeCompound(compound); |
| | for (auto& shape : shapes) { |
| | if (shape.IsNull()) { |
| | continue; |
| | } |
| | hasShape = true; |
| | builder.Add(compound, shape); |
| | } |
| | Shape.setValue(compound); |
| | } |
| |
|
| | if (!hasShape) { |
| | return new App::DocumentObjectExecReturn("no output shape"); |
| | } |
| |
|
| | return DocumentObject::StdReturn; |
| | } |
| |
|
| | |
| |
|
| | namespace App |
| | { |
| | |
| | PROPERTY_SOURCE_TEMPLATE(Path::FeatureAreaPython, Path::FeatureArea) |
| | PROPERTY_SOURCE_TEMPLATE(Path::FeatureAreaViewPython, Path::FeatureAreaView) |
| |
|
| | template<> |
| | const char* Path::FeatureAreaPython::getViewProviderName() const |
| | { |
| | return "PathGui::ViewProviderAreaPython"; |
| | } |
| | template<> |
| | const char* Path::FeatureAreaViewPython::getViewProviderName() const |
| | { |
| | return "PathGui::ViewProviderAreaViewPython"; |
| | } |
| | |
| |
|
| | |
| | template class PathExport FeaturePythonT<Path::FeatureArea>; |
| | } |
| |
|