void ViewProviderDrawingView::onChanged(const App::Property *prop) { App::DocumentObject* obj = getObject(); if (!obj || obj->isRestoring()) { Gui::ViewProviderDocumentObject::onChanged(prop); return; } if (prop == &Visibility) { if(Visibility.getValue()) { show(); } else { hide(); } } else if (prop == &KeepLabel) { QGIView* qgiv = getQView(); if (qgiv) { qgiv->updateView(true); } } Gui::ViewProviderDocumentObject::onChanged(prop); }
void DrawViewSection::onChanged(const App::Property* prop) { if (!isRestoring()) { //Base::Console().Message("TRACE - DVS::onChanged(%s) - %s\n",prop->getName(),Label.getValue()); if (prop == &SectionSymbol) { std::string lblText = "Section " + std::string(SectionSymbol.getValue()) + " - " + std::string(SectionSymbol.getValue()); Label.setValue(lblText); } if (prop == &SectionOrigin) { App::DocumentObject* base = BaseView.getValue(); if (base != nullptr) { base->touch(); } } } if (prop == &FileHatchPattern || prop == &NameGeomPattern ) { if ((!FileHatchPattern.isEmpty()) && (!NameGeomPattern.isEmpty())) { std::vector<PATLineSpec> specs = DrawGeomHatch::getDecodedSpecsFromFile(FileHatchPattern.getValue(),NameGeomPattern.getValue()); m_lineSets.clear(); for (auto& hl: specs) { //hl.dump("hl from section"); LineSet ls; ls.setPATLineSpec(hl); m_lineSets.push_back(ls); } } } DrawView::onChanged(prop); }
const bool TaskTransformedParameters::originalSelected(const Gui::SelectionChanges& msg) { if (msg.Type == Gui::SelectionChanges::AddSelection && originalSelectionMode) { if (strcmp(msg.pDocName, getObject()->getDocument()->getName()) != 0) return false; PartDesign::Transformed* pcTransformed = getObject(); App::DocumentObject* selectedObject = pcTransformed->getDocument()->getObject(msg.pObjectName); if (selectedObject->isDerivedFrom(PartDesign::Additive::getClassTypeId()) || selectedObject->isDerivedFrom(PartDesign::Subtractive::getClassTypeId())) { // Do the same like in TaskDlgTransformedParameters::accept() but without doCommand std::vector<App::DocumentObject*> originals(1,selectedObject); pcTransformed->Originals.setValues(originals); recomputeFeature(); originalSelectionMode = false; return true; } } return false; }
void ViewProviderDatum::attach(App::DocumentObject *obj) { ViewProviderGeometryObject::attach ( obj ); // TODO remove this field (2015-09-08, Fat-Zer) App::DocumentObject* o = getObject(); if (o->getTypeId() == PartDesign::Plane::getClassTypeId()) datumType = QObject::tr("Plane"); else if (o->getTypeId() == PartDesign::Line::getClassTypeId()) datumType = QObject::tr("Line"); else if (o->getTypeId() == PartDesign::Point::getClassTypeId()) datumType = QObject::tr("Point"); else if (o->getTypeId() == PartDesign::CoordinateSystem::getClassTypeId()) datumType = QObject::tr("CoordinateSystem"); SoShapeHints* hints = new SoShapeHints(); hints->shapeType.setValue(SoShapeHints::UNKNOWN_SHAPE_TYPE); hints->vertexOrdering.setValue(SoShapeHints::COUNTERCLOCKWISE); SoDrawStyle* fstyle = new SoDrawStyle(); fstyle->style = SoDrawStyle::FILLED; fstyle->lineWidth = 3; fstyle->pointSize = 5; pPickStyle->style = SoPickStyle::SHAPE; SoMaterialBinding* matBinding = new SoMaterialBinding; matBinding->value = SoMaterialBinding::OVERALL; SoSeparator* sep = new SoSeparator(); sep->addChild(hints); sep->addChild(fstyle); sep->addChild(pPickStyle); sep->addChild(matBinding); sep->addChild(pcShapeMaterial); sep->addChild(pShapeSep); addDisplayMaskMode(sep, "Base"); }
void CmdPartDesignMoveTip::activated(int iMsg) { Q_UNUSED(iMsg); std::vector<App::DocumentObject*> features = getSelection().getObjectsOfType( Part::Feature::getClassTypeId() ); App::DocumentObject* selFeature; PartDesign::Body* body= nullptr; if ( features.size() == 1 ) { selFeature = features.front(); if ( selFeature->getTypeId().isDerivedFrom ( PartDesign::Body::getClassTypeId() ) ) { body = static_cast<PartDesign::Body *> ( selFeature ); } else { body = PartDesignGui::getBodyFor ( selFeature, /* messageIfNot =*/ false ); } } else { selFeature = nullptr; } if (!selFeature) { QMessageBox::warning (0, QObject::tr( "Selection error" ), QObject::tr( "Select exactly one PartDesign feature or a body." ) ); return; } else if (!body) { QMessageBox::warning (0, QObject::tr( "Selection error" ), QObject::tr( "Couldn't determine a body for the selected feature '%s'.", selFeature->Label.getValue() ) ); return; } else if ( !selFeature->isDerivedFrom(PartDesign::Feature::getClassTypeId () ) && selFeature != body && body->BaseFeature.getValue() != selFeature ) { QMessageBox::warning (0, QObject::tr( "Selection error" ), QObject::tr( "Only a solid feature can be the tip of a body." ) ); return; } App::DocumentObject* oldTip = body->Tip.getValue(); if (oldTip == selFeature) { // it's not generally an error, so print only a console message Base::Console().Message ("%s is already the tip of the body", selFeature->getNameInDocument () ); return; } openCommand("Move tip to selected feature"); if (selFeature == body) { doCommand(Doc,"App.activeDocument().%s.Tip = None", body->getNameInDocument()); } else { doCommand(Doc,"App.activeDocument().%s.Tip = App.activeDocument().%s",body->getNameInDocument(), selFeature->getNameInDocument()); // Adjust visibility to show only the Tip feature doCommand(Gui,"Gui.activeDocument().show(\"%s\")", selFeature->getNameInDocument()); } // TOOD: Hide all datum features after the Tip feature? But the user might have already hidden some and wants to see // others, so we would have to remember their state somehow updateActive(); }
Private(ViewProviderPartExt* vp) : ui(new Ui_TaskFaceColors()), view(0), vp(vp) { obj = vp->getObject(); doc = Gui::Application::Instance->getDocument(obj->getDocument()); // build up map edge->face TopTools_IndexedMapOfShape mapOfShape; TopExp_Explorer xp(static_cast<Part::Feature*>(obj)->Shape.getValue(), TopAbs_FACE); while (xp.More()) { mapOfShape.Add(xp.Current()); xp.Next(); } current = vp->DiffuseColor.getValues(); if (current.empty()) current.push_back(vp->ShapeColor.getValue()); perface = current; perface.resize(mapOfShape.Extent(), perface.front()); }
void ShapeBinder::slotChangedObject(const App::DocumentObject& Obj, const App::Property& Prop) { App::Document* doc = getDocument(); if (!doc || doc->testStatus(App::Document::Restoring)) return; if (this == &Obj) return; if (!TraceSupport.getValue()) return; if (!Prop.getTypeId().isDerivedFrom(App::PropertyPlacement::getClassTypeId())) return; Part::Feature* obj = nullptr; std::vector<std::string> subs; ShapeBinder::getFilteredReferences(&Support, obj, subs); if (obj) { if (obj == &Obj) { // the directly referenced object has changed enforceRecompute(); } else if (Obj.hasExtension(App::GroupExtension::getExtensionClassTypeId())) { // check if the changed property belongs to a group-like object // like Body or Part std::vector<App::DocumentObject*> chain; std::vector<App::DocumentObject*> list = getInListRecursive(); chain.insert(chain.end(), list.begin(), list.end()); list = obj->getInListRecursive(); chain.insert(chain.end(), list.begin(), list.end()); auto it = std::find(chain.begin(), chain.end(), &Obj); if (it != chain.end()) { enforceRecompute(); } } } }
App::DocumentObjectExecReturn *Revolution::execute(void) { App::DocumentObject* link = Sketch.getValue(); if (!link) return new App::DocumentObjectExecReturn("No sketch linked"); if (!link->getTypeId().isDerivedFrom(Part::Part2DObject::getClassTypeId())) return new App::DocumentObjectExecReturn("Linked object is not a Sketch or Part2DObject"); Part::Part2DObject* pcSketch=static_cast<Part::Part2DObject*>(link); TopoDS_Shape shape = pcSketch->Shape.getShape()._Shape; if (shape.IsNull()) return new App::DocumentObjectExecReturn("Linked shape object is empty"); // this is a workaround for an obscure OCC bug which leads to empty tessellations // for some faces. Making an explicit copy of the linked shape seems to fix it. // The error only happens when re-computing the shape. if (!this->Shape.getValue().IsNull()) { BRepBuilderAPI_Copy copy(shape); shape = copy.Shape(); if (shape.IsNull()) return new App::DocumentObjectExecReturn("Linked shape object is empty"); } TopExp_Explorer ex; std::vector<TopoDS_Wire> wires; for (ex.Init(shape, TopAbs_WIRE); ex.More(); ex.Next()) { wires.push_back(TopoDS::Wire(ex.Current())); } if (wires.empty()) // there can be several wires return new App::DocumentObjectExecReturn("Linked shape object is not a wire"); // get the Sketch plane Base::Placement SketchPlm = pcSketch->Placement.getValue(); // get reference axis App::DocumentObject *pcReferenceAxis = ReferenceAxis.getValue(); const std::vector<std::string> &subReferenceAxis = ReferenceAxis.getSubValues(); if (pcReferenceAxis && pcReferenceAxis == pcSketch) { bool hasValidAxis=false; Base::Axis axis; if (subReferenceAxis[0] == "V_Axis") { hasValidAxis = true; axis = pcSketch->getAxis(Part::Part2DObject::V_Axis); } else if (subReferenceAxis[0] == "H_Axis") { hasValidAxis = true; axis = pcSketch->getAxis(Part::Part2DObject::H_Axis); } else if (subReferenceAxis[0].size() > 4 && subReferenceAxis[0].substr(0,4) == "Axis") { int AxId = std::atoi(subReferenceAxis[0].substr(4,4000).c_str()); if (AxId >= 0 && AxId < pcSketch->getAxisCount()) { hasValidAxis = true; axis = pcSketch->getAxis(AxId); } } if (hasValidAxis) { axis *= SketchPlm; Base::Vector3d base=axis.getBase(); Base::Vector3d dir=axis.getDirection(); Base.setValue(base.x,base.y,base.z); Axis.setValue(dir.x,dir.y,dir.z); } } // get revolve axis Base::Vector3f b = Base.getValue(); gp_Pnt pnt(b.x,b.y,b.z); Base::Vector3f v = Axis.getValue(); gp_Dir dir(v.x,v.y,v.z); // get the support of the Sketch if any App::DocumentObject* pcSupport = pcSketch->Support.getValue(); Part::Feature *SupportObject = 0; if (pcSupport && pcSupport->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) SupportObject = static_cast<Part::Feature*>(pcSupport); TopoDS_Shape aFace = makeFace(wires); if (aFace.IsNull()) return new App::DocumentObjectExecReturn("Creating a face from sketch failed"); // Rotate the face by half the angle to get revolution symmetric to sketch plane if (Midplane.getValue()) { gp_Trsf mov; mov.SetRotation(gp_Ax1(pnt, dir), Base::toRadians<double>(Angle.getValue()) * (-1.0) / 2.0); TopLoc_Location loc(mov); aFace.Move(loc); } this->positionBySketch(); TopLoc_Location invObjLoc = this->getLocation().Inverted(); pnt.Transform(invObjLoc.Transformation()); dir.Transform(invObjLoc.Transformation()); // Reverse angle if selected double angle = Base::toRadians<double>(Angle.getValue()); if (Reversed.getValue() && !Midplane.getValue()) angle *= (-1.0); try { // revolve the face to a solid BRepPrimAPI_MakeRevol RevolMaker(aFace.Moved(invObjLoc), gp_Ax1(pnt, dir), angle); if (RevolMaker.IsDone()) { TopoDS_Shape result = RevolMaker.Shape(); // if the sketch has a support fuse them to get one result object (PAD!) if (SupportObject) { const TopoDS_Shape& support = SupportObject->Shape.getValue(); if (!support.IsNull() && support.ShapeType() == TopAbs_SOLID) { // set the additive shape property for later usage in e.g. pattern this->AddShape.setValue(result); // Let's call algorithm computing a fuse operation: BRepAlgoAPI_Fuse mkFuse(support.Moved(invObjLoc), result); // Let's check if the fusion has been successful if (!mkFuse.IsDone()) throw Base::Exception("Fusion with support failed"); result = mkFuse.Shape(); } } this->Shape.setValue(result); } else return new App::DocumentObjectExecReturn("Could not revolve the sketch!"); return App::DocumentObject::StdReturn; } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); return new App::DocumentObjectExecReturn(e->GetMessageString()); } }
void CmdPartDesignMoveFeatureInTree::activated(int iMsg) { Q_UNUSED(iMsg); std::vector<App::DocumentObject*> features = getSelection().getObjectsOfType(Part::Feature::getClassTypeId()); if (features.empty()) return; PartDesign::Body *body = PartDesignGui::getBodyFor ( features.front(), false ); App::DocumentObject * bodyBase = nullptr; // sanity check bool allFeaturesFromSameBody = true; if ( body ) { bodyBase= body->BaseFeature.getValue(); for ( auto feat: features ) { if ( !body->hasObject ( feat ) ) { allFeaturesFromSameBody = false; break; } if ( bodyBase== feat) { QMessageBox::warning (0, QObject::tr( "Selection error" ), QObject::tr( "Impossible to move the base feature of a body." ) ); return; } } } if (!body || ! allFeaturesFromSameBody) { QMessageBox::warning (0, QObject::tr( "Selection error" ), QObject::tr( "Select one or more features from the same body." ) ); return; } // Create a list of all features in this body const std::vector<App::DocumentObject*> & model = body->Group.getValues(); // Ask user to select the target feature bool ok; QStringList items; if ( bodyBase ) { items.push_back( QString::fromUtf8 ( bodyBase->Label.getValue () ) ); } else { items.push_back( QObject::tr( "Beginning of the body" ) ); } for ( auto feat: model ) { items.push_back( QString::fromUtf8 ( feat->Label.getValue() ) ); } QString text = QInputDialog::getItem(Gui::getMainWindow(), qApp->translate("PartDesign_MoveFeatureInTree", "Select feature"), qApp->translate("PartDesign_MoveFeatureInTree", "Select a feature from the list"), items, 0, false, &ok); if (!ok) return; int index = items.indexOf(text); // first object is the beginning of the body App::DocumentObject* target = index != 0 ? model[index-1] : nullptr; openCommand("Move an object inside tree"); for ( auto feat: features ) { if ( feat == target ) continue; std::string targetStr; if (target) { targetStr.append("App.activeDocument().").append(target->getNameInDocument()); } else { targetStr = "None"; } // Remove and re-insert the feature to/from the Body // TODO if tip was moved the new position of tip is quite undetermined (2015-08-07, Fat-Zer) // TODO warn the user if we are moving an object to some place before the object's link (2015-08-07, Fat-Zer) doCommand ( Doc,"App.activeDocument().%s.removeObject(App.activeDocument().%s)", body->getNameInDocument(), feat->getNameInDocument() ); doCommand ( Doc, "App.activeDocument().%s.insertObject(App.activeDocument().%s, %s, True)", body->getNameInDocument(), feat->getNameInDocument(), targetStr.c_str () ); } updateActive(); }
void CmdPartDesignMoveFeature::activated(int iMsg) { Q_UNUSED(iMsg); std::vector<App::DocumentObject*> features = getSelection().getObjectsOfType(Part::Feature::getClassTypeId()); if (features.empty()) return; // Check if all features are valid to move if (std::any_of(std::begin(features), std::end(features), [](App::DocumentObject* obj){return !PartDesignGui::isFeatureMovable(obj); })) { //show messagebox and cancel QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Features cannot be moved"), QObject::tr("Some of the selected features have dependencies in the source body")); return; } // Collect dependenies of the selected features std::vector<App::DocumentObject*> dependencies = PartDesignGui::collectMovableDependencies(features); if (!dependencies.empty()) features.insert(std::end(features), std::begin(dependencies), std::end(dependencies)); // Create a list of all bodies in this part std::vector<App::DocumentObject*> bodies = getDocument()->getObjectsOfType(Part::BodyBase::getClassTypeId()); std::set<App::DocumentObject*> source_bodies; for (auto feat : features) { PartDesign::Body* source = PartDesign::Body::findBodyOf(feat); source_bodies.insert(static_cast<App::DocumentObject*>(source)); } std::vector<App::DocumentObject*> target_bodies; for (auto body : bodies) { if (!source_bodies.count(body)) target_bodies.push_back(body); } if (target_bodies.empty()) { QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Features cannot be moved"), QObject::tr("There are no other bodies to move to")); return; } // Ask user to select the target body (remove source bodies from list) bool ok; QStringList items; for (auto body : target_bodies) { items.push_back(QString::fromUtf8(body->Label.getValue())); } QString text = QInputDialog::getItem(Gui::getMainWindow(), qApp->translate("PartDesign_MoveFeature", "Select body"), qApp->translate("PartDesign_MoveFeature", "Select a body from the list"), items, 0, false, &ok); if (!ok) return; int index = items.indexOf(text); if (index < 0) return; PartDesign::Body* target = static_cast<PartDesign::Body*>(target_bodies[index]); openCommand("Move an object"); for (auto feat: features) { // Find body of this feature Part::BodyBase* source = PartDesign::Body::findBodyOf(feat); bool featureWasTip = false; if (source == target) continue; // Remove from the source body if the feature belonged to a body if (source) { featureWasTip = (source->Tip.getValue() == feat); doCommand(Doc,"App.activeDocument().%s.removeObject(App.activeDocument().%s)", source->getNameInDocument(), (feat)->getNameInDocument()); } App::DocumentObject* targetOldTip = target->Tip.getValue(); // Add to target body (always at the Tip) doCommand(Doc,"App.activeDocument().%s.addObject(App.activeDocument().%s)", target->getNameInDocument(), (feat)->getNameInDocument()); // Recompute to update the shape doCommand(Gui,"App.activeDocument().recompute()"); // Adjust visibility of features // TODO: May be something can be done in view provider (2015-08-05, Fat-Zer) // If we removed the tip of the source body, make the new tip visible if ( featureWasTip ) { App::DocumentObject * sourceNewTip = source->Tip.getValue(); if (sourceNewTip) doCommand(Gui,"Gui.activeDocument().show(\"%s\")", sourceNewTip->getNameInDocument()); } // Hide old tip and show new tip (the moved feature) of the target body App::DocumentObject* targetNewTip = target->Tip.getValue(); if ( targetOldTip != targetNewTip ) { if ( targetOldTip ) { doCommand(Gui,"Gui.activeDocument().hide(\"%s\")", targetOldTip->getNameInDocument()); } if (targetNewTip) { doCommand(Gui,"Gui.activeDocument().show(\"%s\")", targetNewTip->getNameInDocument()); } } // Fix sketch support if (feat->getTypeId().isDerivedFrom(Sketcher::SketchObject::getClassTypeId())) { Sketcher::SketchObject *sketch = static_cast<Sketcher::SketchObject*>(feat); try { PartDesignGui::fixSketchSupport(sketch); } catch (Base::Exception &) { QMessageBox::warning( Gui::getMainWindow(), QObject::tr("Sketch plane cannot be migrated"), QObject::tr("Please edit '%1' and redefine it to use a Base or Datum plane as the sketch plane."). arg( QString::fromLatin1( sketch->Label.getValue () ) ) ); } } //relink origin for sketches and datums (coordinates) PartDesignGui::relinkToOrigin(feat, target); } updateActive(); }
const std::list<gp_Trsf> PolarPattern::getTransformations(const std::vector<App::DocumentObject*>) { float angle = Angle.getValue(); if (angle < Precision::Confusion()) throw Base::Exception("Pattern angle too small"); int occurrences = Occurrences.getValue(); if (occurrences < 2) throw Base::Exception("At least two occurrences required"); bool reversed = Reversed.getValue(); double offset; if (std::abs(angle - 360.0) < Precision::Confusion()) offset = Base::toRadians<double>(angle) / occurrences; // Because e.g. two occurrences in 360 degrees need to be 180 degrees apart else offset = Base::toRadians<double>(angle) / (occurrences - 1); App::DocumentObject* refObject = Axis.getValue(); if (refObject == NULL) throw Base::Exception("No axis reference specified"); if (!refObject->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) throw Base::Exception("Axis reference must be edge of a feature"); std::vector<std::string> subStrings = Axis.getSubValues(); if (subStrings.empty() || subStrings[0].empty()) throw Base::Exception("No axis reference specified"); gp_Pnt axbase; gp_Dir axdir; if (refObject->getTypeId().isDerivedFrom(Part::Part2DObject::getClassTypeId())) { Part::Part2DObject* refSketch = static_cast<Part::Part2DObject*>(refObject); Base::Axis axis; if (subStrings[0] == "H_Axis") axis = refSketch->getAxis(Part::Part2DObject::H_Axis); else if (subStrings[0] == "V_Axis") axis = refSketch->getAxis(Part::Part2DObject::V_Axis); else if (subStrings[0] == "N_Axis") axis = refSketch->getAxis(Part::Part2DObject::N_Axis); else if (subStrings[0].size() > 4 && subStrings[0].substr(0,4) == "Axis") { int AxId = std::atoi(subStrings[0].substr(4,4000).c_str()); if (AxId >= 0 && AxId < refSketch->getAxisCount()) axis = refSketch->getAxis(AxId); } axis *= refSketch->Placement.getValue(); axbase = gp_Pnt(axis.getBase().x, axis.getBase().y, axis.getBase().z); axdir = gp_Dir(axis.getDirection().x, axis.getDirection().y, axis.getDirection().z); } else { Part::Feature* refFeature = static_cast<Part::Feature*>(refObject); Part::TopoShape refShape = refFeature->Shape.getShape(); TopoDS_Shape ref = refShape.getSubShape(subStrings[0].c_str()); if (ref.ShapeType() == TopAbs_EDGE) { TopoDS_Edge refEdge = TopoDS::Edge(ref); if (refEdge.IsNull()) throw Base::Exception("Failed to extract axis edge"); BRepAdaptor_Curve adapt(refEdge); if (adapt.GetType() != GeomAbs_Line) throw Base::Exception("Axis edge must be a straight line"); axbase = adapt.Value(adapt.FirstParameter()); axdir = adapt.Line().Direction(); } else { throw Base::Exception("Axis reference must be an edge"); } } TopLoc_Location invObjLoc = this->getLocation().Inverted(); axbase.Transform(invObjLoc.Transformation()); axdir.Transform(invObjLoc.Transformation()); gp_Ax2 axis(axbase, axdir); if (reversed) axis.SetDirection(axis.Direction().Reversed()); // Note: The original feature is NOT included in the list of transformations! Therefore // we start with occurrence number 1, not number 0 std::list<gp_Trsf> transformations; gp_Trsf trans; transformations.push_back(trans); // identity transformation for (int i = 1; i < occurrences; i++) { trans.SetRotation(axis.Axis(), i * offset); transformations.push_back(trans); } return transformations; }
App::DocumentObjectExecReturn *FeatureViewPart::execute(void) { std::stringstream result; std::string ViewName = Label.getValue(); App::DocumentObject* link = Source.getValue(); if (!link) return new App::DocumentObjectExecReturn("No object linked"); if (!link->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) return new App::DocumentObjectExecReturn("Linked object is not a Part object"); TopoDS_Shape shape = static_cast<Part::Feature*>(link)->Shape.getShape()._Shape; if (shape.IsNull()) return new App::DocumentObjectExecReturn("Linked shape object is empty"); Handle( HLRBRep_Algo ) brep_hlr = new HLRBRep_Algo; brep_hlr->Add( shape ); gp_Ax2 transform(gp_Pnt(0,0,0),gp_Dir(0,0,1)); HLRAlgo_Projector projector( transform ); brep_hlr->Projector( projector ); brep_hlr->Update(); brep_hlr->Hide(); // extracting the result sets: HLRBRep_HLRToShape shapes( brep_hlr ); TopoDS_Shape VisiblyEdges; VisiblyEdges = shapes.VCompound(); TopoDS_Shape HiddenEdges; HiddenEdges = shapes.HCompound(); BRepMesh::Mesh(VisiblyEdges,0.1); //HLRBRep_HLRToShape Tool(Hider); //TopoDS_Shape V = Tool.VCompound ();// artes vives vues //TopoDS_Shape V1 = Tool.Rg1LineVCompound();// artes rgulires vues //TopoDS_Shape VN = Tool.RgNLineVCompound();// artes de couture vues //TopoDS_Shape VO = Tool.OutLineVCompound();// contours apparents vus //TopoDS_Shape VI = Tool.IsoLineVCompound();// isoparamtriques vues //TopoDS_Shape H = Tool.HCompound ();// artes vives caches //TopoDS_Shape H1 = Tool.Rg1LineHCompound();// artes rgulires caches //TopoDS_Shape HN = Tool.RgNLineHCompound();// artes de couture caches //TopoDS_Shape HO = Tool.OutLineHCompound();// contours apparents cachs //TopoDS_Shape HI = Tool.IsoLineHCompound();// isoparamtriques caches result << "<g" << " id=\"" << ViewName << "\"" << endl << " stroke=\"rgb(0, 0, 0)\"" << endl << " stroke-width=\"0.35\"" << endl << " stroke-linecap=\"butt\"" << endl << " stroke-linejoin=\"miter\"" << endl << " transform=\"translate("<< X.getValue()<<","<<Y.getValue()<<") scale("<< Scale.getValue()<<","<<Scale.getValue()<<")\"" << endl << " fill=\"none\"" << endl << " >" << endl; TopExp_Explorer edges( VisiblyEdges, TopAbs_EDGE ); for (int i = 1 ; edges.More(); edges.Next(),i++ ) { TopoDS_Edge edge = TopoDS::Edge( edges.Current() ); TopLoc_Location location; Handle( Poly_Polygon3D ) polygon = BRep_Tool::Polygon3D( edge, location ); if ( !polygon.IsNull() ) { const TColgp_Array1OfPnt& nodes = polygon->Nodes(); char c = 'M'; result << "<path id= \"" << ViewName << i << "\" d=\" "; for ( int i = nodes.Lower(); i<= nodes.Upper(); i++ ){ result << c << " " << nodes(i).X() << " " << nodes(i).Y()<< " " ; c = 'L'; } result << "\" />" << endl; } } result << "</g>" << endl; // Apply the resulting fragment ViewResult.setValue(result.str().c_str()); return App::DocumentObject::StdReturn; }
bool SweepWidget::accept() { if (d->loop.isRunning()) return false; Gui::SelectionFilter edgeFilter ("SELECT Part::Feature SUBELEMENT Edge COUNT 1.."); Gui::SelectionFilter partFilter ("SELECT Part::Feature COUNT 1"); bool matchEdge = edgeFilter.match(); bool matchPart = partFilter.match(); if (!matchEdge && !matchPart) { QMessageBox::critical(this, tr("Sweep path"), tr("Select one or more connected edges you want to sweep along.")); return false; } // get the selected object std::string selection; std::string spineObject, spineLabel; const std::vector<Gui::SelectionObject>& result = matchEdge ? edgeFilter.Result[0] : partFilter.Result[0]; selection = result.front().getAsPropertyLinkSubString(); spineObject = result.front().getFeatName(); spineLabel = result.front().getObject()->Label.getValue(); QString list, solid, frenet; if (d->ui.checkSolid->isChecked()) solid = QString::fromLatin1("True"); else solid = QString::fromLatin1("False"); if (d->ui.checkFrenet->isChecked()) frenet = QString::fromLatin1("True"); else frenet = QString::fromLatin1("False"); QTextStream str(&list); int count = d->ui.selector->selectedTreeWidget()->topLevelItemCount(); if (count < 1) { QMessageBox::critical(this, tr("Too few elements"), tr("At least one edge or wire is required.")); return false; } for (int i=0; i<count; i++) { QTreeWidgetItem* child = d->ui.selector->selectedTreeWidget()->topLevelItem(i); QString name = child->data(0, Qt::UserRole).toString(); if (name == QLatin1String(spineObject.c_str())) { QMessageBox::critical(this, tr("Wrong selection"), tr("'%1' cannot be used as profile and path.") .arg(QString::fromUtf8(spineLabel.c_str()))); return false; } str << "App.getDocument('" << d->document.c_str() << "')." << name << ", "; } try { Gui::WaitCursor wc; QString cmd; cmd = QString::fromLatin1( "App.getDocument('%5').addObject('Part::Sweep','Sweep')\n" "App.getDocument('%5').ActiveObject.Sections=[%1]\n" "App.getDocument('%5').ActiveObject.Spine=%2\n" "App.getDocument('%5').ActiveObject.Solid=%3\n" "App.getDocument('%5').ActiveObject.Frenet=%4\n" ) .arg(list) .arg(QLatin1String(selection.c_str())) .arg(solid) .arg(frenet) .arg(QString::fromLatin1(d->document.c_str())); Gui::Document* doc = Gui::Application::Instance->getDocument(d->document.c_str()); if (!doc) throw Base::Exception("Document doesn't exist anymore"); doc->openCommand("Sweep"); Gui::Application::Instance->runPythonCode((const char*)cmd.toLatin1(), false, false); doc->getDocument()->recompute(); App::DocumentObject* obj = doc->getDocument()->getActiveObject(); if (obj && !obj->isValid()) { std::string msg = obj->getStatusString(); doc->abortCommand(); throw Base::Exception(msg); } doc->commitCommand(); } catch (const Base::Exception& e) { QMessageBox::warning(this, tr("Input error"), QString::fromLatin1(e.what())); return false; } return true; }
const std::list<gp_Trsf> LinearPattern::getTransformations(const std::vector<App::DocumentObject*>) { std::string stdDirection = StdDirection.getValue(); float distance = Length.getValue(); if (distance < Precision::Confusion()) throw Base::Exception("Pattern length too small"); int occurrences = Occurrences.getValue(); if (occurrences < 2) throw Base::Exception("At least two occurrences required"); bool reversed = Reversed.getValue(); gp_Dir dir; double offset = distance / (occurrences - 1); if (!stdDirection.empty()) { // Note: The placement code commented out below had the defect of working always on the // absolute X,Y,Z direction, not on the relative coordinate system of the Body feature. // It requires positionBySupport() to be called in Transformed::Execute() AFTER // the call to getTransformations() // New code thanks to logari81 if (stdDirection == "X") { //dir = Base::Axis(Base::Vector3d(0,0,0), Base::Vector3d(1,0,0)); dir = gp_Dir(1,0,0); } else if (stdDirection == "Y") { //dir = Base::Axis(Base::Vector3d(0,0,0), Base::Vector3d(0,1,0)); dir = gp_Dir(0,1,0); } else if(stdDirection == "Z") { //dir = Base::Axis(Base::Vector3d(0,0,0), Base::Vector3d(0,0,1)); dir = gp_Dir(0,0,1); } else { throw Base::Exception("Invalid direction (must be X, Y or Z)"); } } else { App::DocumentObject* refObject = Direction.getValue(); if (refObject == NULL) throw Base::Exception("No direction specified"); if (!refObject->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) throw Base::Exception("Direction reference must be edge or face of a feature"); std::vector<std::string> subStrings = Direction.getSubValues(); if (subStrings.empty() || subStrings[0].empty()) throw Base::Exception("No direction reference specified"); Part::Feature* refFeature = static_cast<Part::Feature*>(refObject); Part::TopoShape refShape = refFeature->Shape.getShape(); TopoDS_Shape ref = refShape.getSubShape(subStrings[0].c_str()); if (ref.ShapeType() == TopAbs_FACE) { TopoDS_Face refFace = TopoDS::Face(ref); if (refFace.IsNull()) throw Base::Exception("Failed to extract direction plane"); BRepAdaptor_Surface adapt(refFace); if (adapt.GetType() != GeomAbs_Plane) throw Base::Exception("Direction face must be planar"); dir = adapt.Plane().Axis().Direction(); //gp_Dir d = adapt.Plane().Axis().Direction(); //dir = Base::Axis(Base::Vector3d(0,0,0), Base::Vector3d(d.X(), d.Y(), d.Z())); } else if (ref.ShapeType() == TopAbs_EDGE) { TopoDS_Edge refEdge = TopoDS::Edge(ref); if (refEdge.IsNull()) throw Base::Exception("Failed to extract direction edge"); BRepAdaptor_Curve adapt(refEdge); if (adapt.GetType() != GeomAbs_Line) throw Base::Exception("Direction edge must be a straight line"); //gp_Dir d = adapt.Line().Direction(); //dir = Base::Axis(Base::Vector3d(0,0,0), Base::Vector3d(d.X(), d.Y(), d.Z())); dir = adapt.Line().Direction(); } else { throw Base::Exception("Direction reference must be edge or face"); } TopLoc_Location invObjLoc = this->getLocation().Inverted(); dir.Transform(invObjLoc.Transformation()); } // get the support placement // TODO: Check for NULL pointer /*Part::Feature* supportFeature = static_cast<Part::Feature*>(originals.front()); if (supportFeature == NULL) throw Base::Exception("Cannot work on invalid support shape"); Base::Placement supportPlacement = supportFeature->Placement.getValue(); dir *= supportPlacement; gp_Vec direction(dir.getDirection().x, dir.getDirection().y, dir.getDirection().z);*/ gp_Vec direction(dir.X(), dir.Y(), dir.Z()); if (reversed) direction.Reverse(); // Note: The original feature is NOT included in the list of transformations! Therefore // we start with occurrence number 1, not number 0 std::list<gp_Trsf> transformations; gp_Trsf trans; transformations.push_back(trans); // identity transformation for (int i = 1; i < occurrences; i++) { trans.SetTranslation(direction * i * offset); transformations.push_back(trans); } return transformations; }
App::DocumentObjectExecReturn *Draft::execute(void) { // Get parameters // Base shape Part::TopoShape TopShape; try { TopShape = getBaseShape(); } catch (Base::Exception& e) { return new App::DocumentObjectExecReturn(e.what()); } // Faces where draft should be applied // Note: Cannot be const reference currently because of BRepOffsetAPI_DraftAngle::Remove() bug, see below std::vector<std::string> SubVals = Base.getSubValuesStartsWith("Face"); if (SubVals.size() == 0) return new App::DocumentObjectExecReturn("No faces specified"); // Draft angle double angle = Angle.getValue() / 180.0 * M_PI; // Pull direction gp_Dir pullDirection; App::DocumentObject* refDirection = PullDirection.getValue(); if (refDirection != NULL) { if (refDirection->getTypeId().isDerivedFrom(PartDesign::Line::getClassTypeId())) { PartDesign::Line* line = static_cast<PartDesign::Line*>(refDirection); Base::Vector3d d = line->getDirection(); pullDirection = gp_Dir(d.x, d.y, d.z); } else if (refDirection->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) { std::vector<std::string> subStrings = PullDirection.getSubValues(); if (subStrings.empty() || subStrings[0].empty()) throw Base::Exception("No pull direction reference specified"); Part::Feature* refFeature = static_cast<Part::Feature*>(refDirection); Part::TopoShape refShape = refFeature->Shape.getShape(); TopoDS_Shape ref = refShape.getSubShape(subStrings[0].c_str()); if (ref.ShapeType() == TopAbs_EDGE) { TopoDS_Edge refEdge = TopoDS::Edge(ref); if (refEdge.IsNull()) throw Base::Exception("Failed to extract pull direction reference edge"); BRepAdaptor_Curve adapt(refEdge); if (adapt.GetType() != GeomAbs_Line) throw Base::Exception("Pull direction reference edge must be linear"); pullDirection = adapt.Line().Direction(); } else { throw Base::Exception("Pull direction reference must be an edge or a datum line"); } } else { throw Base::Exception("Pull direction reference must be an edge of a feature or a datum line"); } TopLoc_Location invObjLoc = this->getLocation().Inverted(); pullDirection.Transform(invObjLoc.Transformation()); } // Neutral plane gp_Pln neutralPlane; App::DocumentObject* refPlane = NeutralPlane.getValue(); if (refPlane == NULL) { // Try to guess a neutral plane from the first selected face // Get edges of first selected face TopoDS_Shape face = TopShape.getSubShape(SubVals[0].c_str()); TopTools_IndexedMapOfShape mapOfEdges; TopExp::MapShapes(face, TopAbs_EDGE, mapOfEdges); bool found = false; for (int i = 1; i <= mapOfEdges.Extent(); i++) { // Note: What happens if mapOfEdges(i) is the degenerated edge of a cone? // But in that case the draft is not possible anyway! BRepAdaptor_Curve c(TopoDS::Edge(mapOfEdges(i))); gp_Pnt p1 = c.Value(c.FirstParameter()); gp_Pnt p2 = c.Value(c.LastParameter()); if (c.IsClosed()) { // Edge is a circle or a circular arc (other types are not allowed for drafting) neutralPlane = gp_Pln(p1, c.Circle().Axis().Direction()); found = true; break; } else { // Edge is linear // Find midpoint of edge and create auxiliary plane through midpoint normal to edge gp_Pnt pm = c.Value((c.FirstParameter() + c.LastParameter()) / 2.0); Handle(Geom_Plane) aux = new Geom_Plane(pm, gp_Dir(p2.X() - p1.X(), p2.Y() - p1.Y(), p2.Z() - p1.Z())); // Intersect plane with face. Is there no easier way? BRepAdaptor_Surface adapt(TopoDS::Face(face), Standard_False); Handle(Geom_Surface) sf = adapt.Surface().Surface(); GeomAPI_IntSS intersector(aux, sf, Precision::Confusion()); if (!intersector.IsDone()) continue; Handle(Geom_Curve) icurve = intersector.Line(1); if (!icurve->IsKind(STANDARD_TYPE(Geom_Line))) continue; // TODO: How to extract the line from icurve without creating an edge first? TopoDS_Edge edge = BRepBuilderAPI_MakeEdge(icurve); BRepAdaptor_Curve c(edge); neutralPlane = gp_Pln(pm, c.Line().Direction()); found = true; break; } } if (!found) throw Base::Exception("No neutral plane specified and none can be guessed"); } else { if (refPlane->getTypeId().isDerivedFrom(PartDesign::Plane::getClassTypeId())) { PartDesign::Plane* plane = static_cast<PartDesign::Plane*>(refPlane); Base::Vector3d b = plane->getBasePoint(); Base::Vector3d n = plane->getNormal(); neutralPlane = gp_Pln(gp_Pnt(b.x, b.y, b.z), gp_Dir(n.x, n.y, n.z)); } else if (refPlane->getTypeId().isDerivedFrom(App::Plane::getClassTypeId())) { neutralPlane = Feature::makePlnFromPlane(refPlane); } else if (refPlane->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) { std::vector<std::string> subStrings = NeutralPlane.getSubValues(); if (subStrings.empty() || subStrings[0].empty()) throw Base::Exception("No neutral plane reference specified"); Part::Feature* refFeature = static_cast<Part::Feature*>(refPlane); Part::TopoShape refShape = refFeature->Shape.getShape(); TopoDS_Shape ref = refShape.getSubShape(subStrings[0].c_str()); if (ref.ShapeType() == TopAbs_FACE) { TopoDS_Face refFace = TopoDS::Face(ref); if (refFace.IsNull()) throw Base::Exception("Failed to extract neutral plane reference face"); BRepAdaptor_Surface adapt(refFace); if (adapt.GetType() != GeomAbs_Plane) throw Base::Exception("Neutral plane reference face must be planar"); neutralPlane = adapt.Plane(); } else if (ref.ShapeType() == TopAbs_EDGE) { if (refDirection != NULL) { // Create neutral plane through edge normal to pull direction TopoDS_Edge refEdge = TopoDS::Edge(ref); if (refEdge.IsNull()) throw Base::Exception("Failed to extract neutral plane reference edge"); BRepAdaptor_Curve c(refEdge); if (c.GetType() != GeomAbs_Line) throw Base::Exception("Neutral plane reference edge must be linear"); double a = c.Line().Angle(gp_Lin(c.Value(c.FirstParameter()), pullDirection)); if (std::fabs(a - M_PI_2) > Precision::Confusion()) throw Base::Exception("Neutral plane reference edge must be normal to pull direction"); neutralPlane = gp_Pln(c.Value(c.FirstParameter()), pullDirection); } else { throw Base::Exception("Neutral plane reference can only be an edge if pull direction is defined"); } } else { throw Base::Exception("Neutral plane reference must be a face"); } } else { throw Base::Exception("Neutral plane reference must be face of a feature or a datum plane"); } TopLoc_Location invObjLoc = this->getLocation().Inverted(); neutralPlane.Transform(invObjLoc.Transformation()); } if (refDirection == NULL) { // Choose pull direction normal to neutral plane pullDirection = neutralPlane.Axis().Direction(); } // Reversed pull direction bool reversed = Reversed.getValue(); if (reversed) angle *= -1.0; this->positionByBaseFeature(); // create an untransformed copy of the base shape Part::TopoShape baseShape(TopShape); baseShape.setTransform(Base::Matrix4D()); try { BRepOffsetAPI_DraftAngle mkDraft; // Note: // LocOpe_SplitDrafts can split a face with a wire and apply draft to both parts // Not clear though whether the face must have free boundaries // LocOpe_DPrism can create a stand-alone draft prism. The sketch can only have a single // wire, though. // BRepFeat_MakeDPrism requires a support for the operation but will probably support multiple // wires in the sketch bool success; do { success = true; mkDraft.Init(baseShape.getShape()); for (std::vector<std::string>::iterator it=SubVals.begin(); it != SubVals.end(); ++it) { TopoDS_Face face = TopoDS::Face(baseShape.getSubShape(it->c_str())); // TODO: What is the flag for? mkDraft.Add(face, pullDirection, angle, neutralPlane); if (!mkDraft.AddDone()) { // Note: the function ProblematicShape returns the face on which the error occurred // Note: mkDraft.Remove() stumbles on a bug in Draft_Modification::Remove() and is // therefore unusable. See http://forum.freecadweb.org/viewtopic.php?f=10&t=3209&start=10#p25341 // The only solution is to discard mkDraft and start over without the current face // mkDraft.Remove(face); Base::Console().Error("Adding face failed on %s. Omitted\n", it->c_str()); success = false; SubVals.erase(it); break; } } } while (!success); mkDraft.Build(); if (!mkDraft.IsDone()) return new App::DocumentObjectExecReturn("Failed to create draft"); TopoDS_Shape shape = mkDraft.Shape(); if (shape.IsNull()) return new App::DocumentObjectExecReturn("Resulting shape is null"); this->Shape.setValue(getSolid(shape)); return App::DocumentObject::StdReturn; } catch (Standard_Failure) { Handle(Standard_Failure) e = Standard_Failure::Caught(); return new App::DocumentObjectExecReturn(e->GetMessageString()); } }
PyObject* Application::sExport(PyObject * /*self*/, PyObject *args,PyObject * /*kwd*/) { PyObject* object; char* Name; if (!PyArg_ParseTuple(args, "Oet",&object,"utf-8",&Name)) return NULL; std::string Utf8Name = std::string(Name); PyMem_Free(Name); PY_TRY { App::Document* doc = 0; Py::Sequence list(object); for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) { PyObject* item = (*it).ptr(); if (PyObject_TypeCheck(item, &(App::DocumentObjectPy::Type))) { App::DocumentObject* obj = static_cast<App::DocumentObjectPy*>(item)->getDocumentObjectPtr(); doc = obj->getDocument(); break; } } QString fileName = QString::fromUtf8(Utf8Name.c_str()); QFileInfo fi; fi.setFile(fileName); QString ext = fi.suffix().toLower(); if (ext == QLatin1String("iv") || ext == QLatin1String("wrl") || ext == QLatin1String("vrml") || ext == QLatin1String("wrz")) { // build up the graph SoSeparator* sep = new SoSeparator(); sep->ref(); for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) { PyObject* item = (*it).ptr(); if (PyObject_TypeCheck(item, &(App::DocumentObjectPy::Type))) { App::DocumentObject* obj = static_cast<App::DocumentObjectPy*>(item)->getDocumentObjectPtr(); Gui::ViewProvider* vp = Gui::Application::Instance->getViewProvider(obj); if (vp) { sep->addChild(vp->getRoot()); } } } SoGetPrimitiveCountAction action; action.setCanApproximate(true); action.apply(sep); bool binary = false; if (action.getTriangleCount() > 100000 || action.getPointCount() > 30000 || action.getLineCount() > 10000) binary = true; SoFCDB::writeToFile(sep, Utf8Name.c_str(), binary); sep->unref(); } else if (ext == QLatin1String("pdf")) { // get the view that belongs to the found document Gui::Document* gui_doc = Application::Instance->getDocument(doc); if (gui_doc) { Gui::MDIView* view = gui_doc->getActiveView(); if (view) { View3DInventor* view3d = qobject_cast<View3DInventor*>(view); if (view3d) view3d->viewAll(); QPrinter printer(QPrinter::ScreenResolution); printer.setOutputFormat(QPrinter::PdfFormat); printer.setOutputFileName(fileName); view->print(&printer); } } } else { Base::Console().Error("File type '%s' not supported\n", ext.toLatin1().constData()); } } PY_CATCH; Py_Return; }
void DlgExtrusion::apply() { if (ui->treeWidget->selectedItems().isEmpty()) { QMessageBox::critical(this, windowTitle(), tr("Select a shape for extrusion, first.")); return; } Gui::WaitCursor wc; App::Document* activeDoc = App::GetApplication().getDocument(this->document.c_str()); if (!activeDoc) { QMessageBox::critical(this, windowTitle(), tr("The document '%1' doesn't exist.").arg(QString::fromUtf8(this->label.c_str()))); return; } activeDoc->openTransaction("Extrude"); Base::Reference<ParameterGrp> hGrp = App::GetApplication().GetUserParameter() .GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/Part"); bool addBaseName = hGrp->GetBool("AddBaseObjectName", false); QString shape, type, name, label; QList<QTreeWidgetItem *> items = ui->treeWidget->selectedItems(); for (QList<QTreeWidgetItem *>::iterator it = items.begin(); it != items.end(); ++it) { shape = (*it)->data(0, Qt::UserRole).toString(); type = QString::fromLatin1("Part::Extrusion"); if (addBaseName) { QString baseName = QString::fromLatin1("Extrude_%1").arg(shape); label = QString::fromLatin1("%1_Extrude").arg((*it)->text(0)); name = QString::fromLatin1(activeDoc->getUniqueObjectName((const char*)baseName.toLatin1()).c_str()); } else { name = QString::fromLatin1(activeDoc->getUniqueObjectName("Extrude").c_str()); label = name; } double len = ui->dirLen->value(); double dirX = ui->dirX->value(); double dirY = ui->dirY->value(); double dirZ = ui->dirZ->value(); double angle = ui->taperAngle->value().getValue(); bool makeSolid = ui->makeSolid->isChecked(); // inspect geometry App::DocumentObject* obj = activeDoc->getObject((const char*)shape.toLatin1()); if (!obj || !obj->isDerivedFrom(Part::Feature::getClassTypeId())) continue; Part::Feature* fea = static_cast<Part::Feature*>(obj); const TopoDS_Shape& data = fea->Shape.getValue(); if (data.IsNull()) continue; // check for planes if (ui->checkNormal->isChecked() && data.ShapeType() == TopAbs_FACE) { BRepAdaptor_Surface adapt(TopoDS::Face(data)); if (adapt.GetType() == GeomAbs_Plane) { double u = 0.5*(adapt.FirstUParameter() + adapt.LastUParameter()); double v = 0.5*(adapt.FirstVParameter() + adapt.LastVParameter()); BRepLProp_SLProps prop(adapt,u,v,1,Precision::Confusion()); if (prop.IsNormalDefined()) { gp_Pnt pnt; gp_Vec vec; // handles the orientation state of the shape BRepGProp_Face(TopoDS::Face(data)).Normal(u,v,pnt,vec); dirX = vec.X(); dirY = vec.Y(); dirZ = vec.Z(); } } } QString code = QString::fromLatin1( "FreeCAD.getDocument(\"%1\").addObject(\"%2\",\"%3\")\n" "FreeCAD.getDocument(\"%1\").%3.Base = FreeCAD.getDocument(\"%1\").%4\n" "FreeCAD.getDocument(\"%1\").%3.Dir = (%5,%6,%7)\n" "FreeCAD.getDocument(\"%1\").%3.Solid = (%8)\n" "FreeCAD.getDocument(\"%1\").%3.TaperAngle = (%9)\n" "FreeCADGui.getDocument(\"%1\").%4.Visibility = False\n" "FreeCAD.getDocument(\"%1\").%3.Label = '%10'\n") .arg(QString::fromLatin1(this->document.c_str())) .arg(type).arg(name).arg(shape) .arg(dirX*len) .arg(dirY*len) .arg(dirZ*len) .arg(makeSolid ? QLatin1String("True") : QLatin1String("False")) .arg(angle) .arg(label); Gui::Application::Instance->runPythonCode((const char*)code.toLatin1()); QByteArray to = name.toLatin1(); QByteArray from = shape.toLatin1(); Gui::Command::copyVisual(to, "ShapeColor", from); Gui::Command::copyVisual(to, "LineColor", from); Gui::Command::copyVisual(to, "PointColor", from); } activeDoc->commitTransaction(); try { ui->statusLabel->clear(); activeDoc->recompute(); ui->statusLabel->setText(QString::fromLatin1 ("<span style=\" color:#55aa00;\">%1</span>").arg(tr("Succeeded"))); } catch (const std::exception& e) { ui->statusLabel->setText(QString::fromLatin1 ("<span style=\" color:#ff0000;\">%1</span>").arg(tr("Failed"))); Base::Console().Error("%s\n", e.what()); } catch (const Base::Exception& e) { ui->statusLabel->setText(QString::fromLatin1 ("<span style=\" color:#ff0000;\">%1</span>").arg(tr("Failed"))); Base::Console().Error("%s\n", e.what()); } catch (...) { ui->statusLabel->setText(QString::fromLatin1 ("<span style=\" color:#ff0000;\">%1</span>").arg(tr("Failed"))); Base::Console().Error("General error in extrusion\n"); } }
App::DocumentObject* TaskFeaturePick::makeCopy(App::DocumentObject* obj, std::string sub, bool independent) { App::DocumentObject* copy = nullptr; // Check for null to avoid segfault if (!obj) return copy; if( independent && (obj->isDerivedFrom(Sketcher::SketchObject::getClassTypeId()) || obj->isDerivedFrom(PartDesign::FeaturePrimitive::getClassTypeId()))) { //we do know that the created instance is a document object, as obj is one. But we do not know which //exact type auto name = std::string("Copy") + std::string(obj->getNameInDocument()); copy = App::GetApplication().getActiveDocument()->addObject(obj->getTypeId().getName(), name.c_str()); //copy over all properties std::vector<App::Property*> props; std::vector<App::Property*> cprops; obj->getPropertyList(props); copy->getPropertyList(cprops); auto it = cprops.begin(); for( App::Property* prop : props ) { //independent copies don't have links and are not attached if(independent && ( prop->getTypeId().isDerivedFrom(App::PropertyLink::getClassTypeId()) || prop->getTypeId().isDerivedFrom(App::PropertyLinkList::getClassTypeId()) || prop->getTypeId().isDerivedFrom(App::PropertyLinkSub::getClassTypeId()) || prop->getTypeId().isDerivedFrom(App::PropertyLinkSubList::getClassTypeId())|| ( prop->getGroup() && strcmp(prop->getGroup(),"Attachment")==0) )) { ++it; continue; } App::Property* cprop = *it++; if( strcmp(prop->getName(), "Label") == 0 ) { static_cast<App::PropertyString*>(cprop)->setValue(name.c_str()); continue; } cprop->Paste(*prop); //we are a independent copy, therefore no external geometry was copied. WE therefore can delete all //constraints if(obj->isDerivedFrom(Sketcher::SketchObject::getClassTypeId())) static_cast<Sketcher::SketchObject*>(copy)->delConstraintsToExternal(); } } else { std::string name; if(!independent) name = std::string("Reference"); else name = std::string("Copy"); name += std::string(obj->getNameInDocument()); std::string entity; if(!sub.empty()) entity = sub; Part::PropertyPartShape* shapeProp = nullptr; // TODO Replace it with commands (2015-09-11, Fat-Zer) if(obj->isDerivedFrom(Part::Datum::getClassTypeId())) { copy = App::GetApplication().getActiveDocument()->addObject( obj->getClassTypeId().getName(), name.c_str() ); //we need to reference the individual datums and make again datums. This is important as //datum adjust their size dependent on the part size, hence simply copying the shape is //not enough long int mode = mmDeactivated; Part::Datum *datumCopy = static_cast<Part::Datum*>(copy); if(obj->getTypeId() == PartDesign::Point::getClassTypeId()) { mode = mm0Vertex; } else if(obj->getTypeId() == PartDesign::Line::getClassTypeId()) { mode = mm1TwoPoints; } else if(obj->getTypeId() == PartDesign::Plane::getClassTypeId()) { mode = mmFlatFace; } else return copy; // TODO Recheck this. This looks strange in case of independent copy (2015-10-31, Fat-Zer) if(!independent) { datumCopy->Support.setValue(obj, entity.c_str()); datumCopy->MapMode.setValue(mode); } else if(!entity.empty()) { datumCopy->Shape.setValue(static_cast<Part::Datum*>(obj)->Shape.getShape().getSubShape(entity.c_str())); } else { datumCopy->Shape.setValue(static_cast<Part::Datum*>(obj)->Shape.getValue()); } } else if(obj->getTypeId() == PartDesign::ShapeBinder::getClassTypeId() || obj->isDerivedFrom(Part::Feature::getClassTypeId())) { copy = App::GetApplication().getActiveDocument()->addObject("PartDesign::ShapeBinder", name.c_str()); if(!independent) static_cast<PartDesign::ShapeBinder*>(copy)->Support.setValue(obj, entity.c_str()); else shapeProp = &static_cast<PartDesign::ShapeBinder*>(copy)->Shape; } if(independent && shapeProp) { if(entity.empty()) shapeProp->setValue(static_cast<Part::Feature*>(obj)->Shape.getValue()); else shapeProp->setValue(static_cast<Part::Feature*>(obj)->Shape.getShape().getSubShape(entity.c_str())); } } return copy; }
App::DocumentObjectExecReturn *FeatureViewSpreadsheet::execute(void) { // quick tests App::DocumentObject* link = Source.getValue(); std::string scellstart = CellStart.getValue(); std::string scellend = CellEnd.getValue(); if (!link) return new App::DocumentObjectExecReturn("No spreadsheet linked"); if (!link->getTypeId().isDerivedFrom(Spreadsheet::Sheet::getClassTypeId())) return new App::DocumentObjectExecReturn("The linked object is not a spreadsheet"); if ( (scellstart.empty()) || (scellend.empty()) ) return new App::DocumentObjectExecReturn("Empty cell value"); // build a list of available colums: A, B, C, ... AA, AB, ... ZY, ZZ. std::string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; std::vector<std::string> availcolumns; for (int i=0; i<26; ++i) { std::stringstream s; s << alphabet[i]; availcolumns.push_back(s.str()); } for (int i=0; i<26; ++i) { for (int j=0; i<26; ++i) { std::stringstream s; s << alphabet[i] << alphabet[j]; availcolumns.push_back(s.str()); } } // build rows range and columns range std::vector<std::string> columns; std::vector<int> rows; try { for (unsigned int i=0; i<scellstart.length(); ++i) { if (isdigit(scellstart[i])) { columns.push_back(scellstart.substr(0,i)); rows.push_back(std::atoi(scellstart.substr(i,scellstart.length()-1).c_str())); } } for (unsigned int i=0; i<scellend.length(); ++i) { if (isdigit(scellend[i])) { std::string startcol = columns.back(); std::string endcol = scellend.substr(0,i); bool valid = false; for (std::vector<std::string>::const_iterator j = availcolumns.begin(); j != availcolumns.end(); ++j) { if ( (*j) == startcol) { if ( (*j) != endcol) { valid = true; } } else { if (valid) { if ( (*j) == endcol) { columns.push_back((*j)); valid = false; } else { columns.push_back((*j)); } } } } int endrow = std::atoi(scellend.substr(i,scellend.length()-1).c_str()); for (int j=rows.back()+1; j<=endrow; ++j) { rows.push_back(j); } } } } catch (std::exception) { return new App::DocumentObjectExecReturn("Invalid cell range"); } // create the containing group std::string ViewName = Label.getValue(); std::stringstream result,hr,hg,hb; const App::Color& c = Color.getValue(); hr << hex << setfill('0') << setw(2) << (int)(255.0*c.r); hg << hex << setfill('0') << setw(2) << (int)(255.0*c.g); hb << hex << setfill('0') << setw(2) << (int)(255.0*c.b); result << "<g id=\"" << ViewName << "\" transform=\"translate(" << X.getValue() << "," << Y.getValue() << ")" << " rotate(" << Rotation.getValue() << ")" << " scale(" << Scale.getValue() << ")\">" << endl; // fill the cells float rowoffset = 0.0; float coloffset = 0.0; float cellheight = 100; float cellwidth = 100; std::string celltext; Spreadsheet::Sheet* sheet = static_cast<Spreadsheet::Sheet*>(link); std::vector<std::string> skiplist; for (std::vector<std::string>::const_iterator col = columns.begin(); col != columns.end(); ++col) { // create a group for each column result << " <g id=\"" << ViewName << "_col" << (*col) << "\">" << endl; for (std::vector<int>::const_iterator row = rows.begin(); row != rows.end(); ++row) { // get cell size std::stringstream srow; srow << (*row); App::CellAddress address((*col) + srow.str()); cellwidth = sheet->getColumnWidth(address.col()); cellheight = sheet->getRowHeight(address.row()); celltext = ""; // get the text App::Property* prop = sheet->getPropertyByName(address.toString().c_str()); std::stringstream field; if (prop != 0) { if (prop->isDerivedFrom((App::PropertyQuantity::getClassTypeId()))) field << static_cast<App::PropertyQuantity*>(prop)->getValue(); else if (prop->isDerivedFrom((App::PropertyFloat::getClassTypeId()))) field << static_cast<App::PropertyFloat*>(prop)->getValue(); else if (prop->isDerivedFrom((App::PropertyString::getClassTypeId()))) field << static_cast<App::PropertyString*>(prop)->getValue(); else assert(0); celltext = field.str(); } // get colors, style, alignment and span int alignment; std::string bcolor = "none"; std::string fcolor = "#" + hr.str() + hg.str() + hb.str(); std::string textstyle = ""; Spreadsheet::Cell* cell = sheet->getCell(address); if (cell) { App::Color f,b; std::set<std::string> st; int colspan, rowspan; if (cell->getBackground(b)) { std::stringstream br,bg,bb; br << hex << setfill('0') << setw(2) << (int)(255.0*b.r); bg << hex << setfill('0') << setw(2) << (int)(255.0*b.g); bb << hex << setfill('0') << setw(2) << (int)(255.0*b.b); bcolor = "#" + br.str() + bg.str() + bb.str(); } if (cell->getForeground(f)) { std::stringstream fr,fg,fb; fr << hex << setfill('0') << setw(2) << (int)(255.0*f.r); fg << hex << setfill('0') << setw(2) << (int)(255.0*f.g); fb << hex << setfill('0') << setw(2) << (int)(255.0*f.b); fcolor = "#" + fr.str() + fg.str() + fb.str(); } if (cell->getStyle(st)) { for (std::set<std::string>::const_iterator i = st.begin(); i != st.end(); ++i) { if ((*i) == "bold") textstyle = textstyle + "font-weight: bold; "; else if ((*i) == "italic") textstyle = textstyle + "font-style: italic; "; else if ((*i) == "underline") textstyle = textstyle + "text-decoration: underline; "; } } if (cell->getSpans(rowspan,colspan)) { for (int i=0; i<colspan; ++i) { for (int j=0; j<rowspan; ++j) { App::CellAddress nextcell(address.row()+j,address.col()+i); if (i > 0) cellwidth = cellwidth + sheet->getColumnWidth(nextcell.col()); if (j > 0) cellheight = cellheight + sheet->getRowHeight(nextcell.row()); if ( (i > 0) || (j > 0) ) skiplist.push_back(nextcell.toString()); } } } cell->getAlignment(alignment); } // skip cell if found in skiplist if (std::find(skiplist.begin(), skiplist.end(), address.toString()) == skiplist.end()) { result << " <rect x=\"" << coloffset << "\" y=\"" << rowoffset << "\" width=\"" << cellwidth << "\" height=\"" << cellheight << "\" style=\"fill:" << bcolor << ";stroke-width:" << LineWidth.getValue()/Scale.getValue() << ";stroke:#" << hr.str() << hg.str() << hb.str() << ";\" />" << endl; if (alignment & Spreadsheet::Cell::ALIGNMENT_LEFT) result << " <text style=\"" << textstyle << "\" x=\"" << coloffset + FontSize.getValue()/2 << "\" y=\"" << rowoffset + 0.75 * cellheight << "\" font-family=\"" ; if (alignment & Spreadsheet::Cell::ALIGNMENT_HCENTER) result << " <text text-anchor=\"middle\" style=\"" << textstyle << "\" x=\"" << coloffset + cellwidth/2 << "\" y=\"" << rowoffset + 0.75 * cellheight << "\" font-family=\"" ; if (alignment & Spreadsheet::Cell::ALIGNMENT_RIGHT) result << " <text text-anchor=\"end\" style=\"" << textstyle << "\" x=\"" << coloffset + (cellwidth - FontSize.getValue()/2) << "\" y=\"" << rowoffset + 0.75 * cellheight << "\" font-family=\"" ; result << Font.getValue() << "\"" << " font-size=\"" << FontSize.getValue() << "\"" << " fill=\"" << fcolor << "\">" << celltext << "</text>" << endl; } rowoffset = rowoffset + cellheight; } result << " </g>" << endl; rowoffset = 0.0; coloffset = coloffset + cellwidth; } // close the containing group result << "</g>" << endl; // Apply the resulting fragment ViewResult.setValue(result.str().c_str()); return App::DocumentObject::StdReturn; }
void SelectionSingleton::slotDeletedObject(const App::DocumentObject& Obj) { // remove also from the selection, if selected Selection().rmvSelection( Obj.getDocument()->getName(), Obj.getNameInDocument() ); }
App::DocumentObjectExecReturn *DrawViewDetail::execute(void) { if (!keepUpdated()) { return App::DocumentObject::StdReturn; } App::DocumentObject* baseObj = BaseView.getValue(); if (!baseObj) { Base::Console().Log("INFO - DVD::execute - No BaseView - creation?\n"); return DrawView::execute(); } DrawViewPart* dvp = nullptr; if (!baseObj->getTypeId().isDerivedFrom(TechDraw::DrawViewPart::getClassTypeId())) { return new App::DocumentObjectExecReturn("BaseView object is not a DrawViewPart object"); } else { dvp = static_cast<DrawViewPart*>(baseObj); } TopoDS_Shape shape = dvp->getSourceShapeFused(); if (shape.IsNull()) { return new App::DocumentObjectExecReturn("DVD - Linked shape object is invalid"); } Base::Vector3d anchor = AnchorPoint.getValue(); //this is a 2D point (in unrotated coords) Base::Vector3d dirDetail = dvp->Direction.getValue(); double shapeRotate = dvp->Rotation.getValue(); //degrees CW? if (dvp->isDerivedFrom(TechDraw::DrawProjGroupItem::getClassTypeId())) { DrawProjGroupItem* dpgi= static_cast<TechDraw::DrawProjGroupItem*>(dvp); shapeRotate += dpgi->getRotateAngle() * 180.0/M_PI; // to degrees from radians } double radius = getFudgeRadius(); double scale = getScale(); BRepBuilderAPI_Copy BuilderCopy(shape); TopoDS_Shape myShape = BuilderCopy.Shape(); //rotate the copied shape to match orientation of BaseView and center it on origin gp_Pnt gpCenter = TechDrawGeometry::findCentroid(myShape, //centre of unrotated shape dirDetail); Base::Vector3d shapeCenter = Base::Vector3d(gpCenter.X(),gpCenter.Y(),gpCenter.Z()); gp_Ax2 viewAxis = getViewAxis(shapeCenter, dirDetail, false); myShape = TechDrawGeometry::rotateShape(myShape, //rotate to match Base shape viewAxis, -shapeRotate); myShape = TechDrawGeometry::moveShape(myShape, //centre on origin -shapeCenter); // shapeCenter = Base::Vector3d(0.0,0.0,0.0); gpCenter = TechDrawGeometry::findCentroid(myShape, dirDetail); shapeCenter = Base::Vector3d(gpCenter.X(),gpCenter.Y(),gpCenter.Z()); Bnd_Box bbxSource; bbxSource.SetGap(0.0); BRepBndLib::Add(myShape, bbxSource); double diag = sqrt(bbxSource.SquareExtent()); Base::Vector3d extentFar,extentNear; extentFar = shapeCenter + dirDetail * diag; extentNear = shapeCenter + dirDetail * diag * -1.0; anchor = Base::Vector3d(anchor.x,anchor.y, 0.0); viewAxis = getViewAxis(shapeCenter, dirDetail, false); //change view axis to (0,0,0) Base::Vector3d offsetCenter3D = DrawUtil::toR3(viewAxis, anchor); //displacement in R3 Base::Vector3d stdZ(0.0,0.0,1.0); if (DrawUtil::checkParallel(dirDetail,stdZ)) { extentNear = extentNear + offsetCenter3D; } else { extentNear = extentNear - offsetCenter3D; } gp_Dir cylDir(dirDetail.x,dirDetail.y,dirDetail.z); gp_Pnt cylPoint(extentNear.x,extentNear.y,extentNear.z); gp_Ax2 cylAxis(cylPoint,cylDir); BRepPrimAPI_MakeCylinder mkCyl(cylAxis, radius, (extentFar-extentNear).Length()); TopoDS_Shell sh = mkCyl.Cylinder().Shell(); BRepBuilderAPI_MakeSolid mkSol(sh); TopoDS_Solid tool = mkSol.Solid(); BRepAlgoAPI_Common mkCommon(myShape,tool); if (!mkCommon.IsDone()) { Base::Console().Log("DVD::execute - mkCommon not done\n"); return new App::DocumentObjectExecReturn("DVD::execute - mkCommon not done"); } if (mkCommon.Shape().IsNull()) { Base::Console().Log("DVD::execute - mkCommon.Shape is Null\n"); return new App::DocumentObjectExecReturn("DVD::execute - mkCommon.Shape is Null"); } //Did we get a solid? TopExp_Explorer xp; xp.Init(mkCommon.Shape(),TopAbs_SOLID); if (!(xp.More() == Standard_True)) { Base::Console().Message("DVD::execute - mkCommon.Shape is not a solid!\n"); } TopoDS_Shape detail = mkCommon.Shape(); Bnd_Box testBox; testBox.SetGap(0.0); BRepBndLib::Add(detail, testBox); if (testBox.IsVoid()) { Base::Console().Message("DrawViewDetail - detail area contains no geometry\n"); return new App::DocumentObjectExecReturn("DVDetail - detail area contains no geometry"); } //for debugging show compound instead of common // BRep_Builder builder; // TopoDS_Compound Comp; // builder.MakeCompound(Comp); // builder.Add(Comp, tool); // builder.Add(Comp, myShape); gp_Pnt inputCenter; try { inputCenter = TechDrawGeometry::findCentroid(tool, Direction.getValue()); TopoDS_Shape mirroredShape = TechDrawGeometry::mirrorShape(detail, inputCenter, scale); viewAxis = getViewAxis(Base::Vector3d(inputCenter.X(),inputCenter.Y(),inputCenter.Z()),Direction.getValue()); if (!DrawUtil::fpCompare(Rotation.getValue(),0.0)) { mirroredShape = TechDrawGeometry::rotateShape(mirroredShape, viewAxis, Rotation.getValue()); //degrees cw? } geometryObject = buildGeometryObject(mirroredShape,viewAxis); geometryObject->pruneVertexGeom(Base::Vector3d(0.0,0.0,0.0),Radius.getValue() * scale); //remove vertices beyond clipradius #if MOD_TECHDRAW_HANDLE_FACES if (handleFaces()) { try { extractFaces(); } catch (Standard_Failure& e4) { Base::Console().Log("LOG - DVD::execute - extractFaces failed for %s - %s **\n",getNameInDocument(),e4.GetMessageString()); return new App::DocumentObjectExecReturn(e4.GetMessageString()); } } #endif //#if MOD_TECHDRAW_HANDLE_FACES } catch (Standard_Failure& e1) { Base::Console().Log("LOG - DVD::execute - base shape failed for %s - %s **\n",getNameInDocument(),e1.GetMessageString()); return new App::DocumentObjectExecReturn(e1.GetMessageString()); } requestPaint(); dvp->requestPaint(); return App::DocumentObject::StdReturn; }
void ProfileBased::getAxis(const App::DocumentObject *pcReferenceAxis, const std::vector<std::string> &subReferenceAxis, Base::Vector3d& base, Base::Vector3d& dir) { dir = Base::Vector3d(0,0,0); // If unchanged signals that no valid axis was found if (pcReferenceAxis == NULL) return; App::DocumentObject* profile = Profile.getValue(); gp_Pln sketchplane; if (profile->getTypeId().isDerivedFrom(Part::Part2DObject::getClassTypeId())) { Part::Part2DObject* sketch = getVerifiedSketch(); Base::Placement SketchPlm = sketch->Placement.getValue(); Base::Vector3d SketchVector = Base::Vector3d(0, 0, 1); Base::Rotation SketchOrientation = SketchPlm.getRotation(); SketchOrientation.multVec(SketchVector, SketchVector); Base::Vector3d SketchPos = SketchPlm.getPosition(); sketchplane = gp_Pln(gp_Pnt(SketchPos.x, SketchPos.y, SketchPos.z), gp_Dir(SketchVector.x, SketchVector.y, SketchVector.z)); if (pcReferenceAxis == profile) { bool hasValidAxis = false; Base::Axis axis; if (subReferenceAxis[0] == "V_Axis") { hasValidAxis = true; axis = sketch->getAxis(Part::Part2DObject::V_Axis); } else if (subReferenceAxis[0] == "H_Axis") { hasValidAxis = true; axis = sketch->getAxis(Part::Part2DObject::H_Axis); } else if (subReferenceAxis[0].size() > 4 && subReferenceAxis[0].substr(0, 4) == "Axis") { int AxId = std::atoi(subReferenceAxis[0].substr(4, 4000).c_str()); if (AxId >= 0 && AxId < sketch->getAxisCount()) { hasValidAxis = true; axis = sketch->getAxis(AxId); } } if (hasValidAxis) { axis *= SketchPlm; base = axis.getBase(); dir = axis.getDirection(); return; } //else - an edge of the sketch was selected as an axis } } else if (profile->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) { Base::Placement SketchPlm = getVerifiedObject()->Placement.getValue(); Base::Vector3d SketchVector = getProfileNormal(); Base::Vector3d SketchPos = SketchPlm.getPosition(); sketchplane = gp_Pln(gp_Pnt(SketchPos.x, SketchPos.y, SketchPos.z), gp_Dir(SketchVector.x, SketchVector.y, SketchVector.z)); } // get reference axis if (pcReferenceAxis->getTypeId().isDerivedFrom(PartDesign::Line::getClassTypeId())) { const PartDesign::Line* line = static_cast<const PartDesign::Line*>(pcReferenceAxis); base = line->getBasePoint(); dir = line->getDirection(); // Check that axis is perpendicular with sketch plane! if (sketchplane.Axis().Direction().IsParallel(gp_Dir(dir.x, dir.y, dir.z), Precision::Angular())) throw Base::ValueError("Rotation axis must not be perpendicular with the sketch plane"); return; } if (pcReferenceAxis->getTypeId().isDerivedFrom(App::Line::getClassTypeId())) { const App::Line* line = static_cast<const App::Line*>(pcReferenceAxis); base = Base::Vector3d(0,0,0); line->Placement.getValue().multVec(Base::Vector3d (1,0,0), dir); // Check that axis is perpendicular with sketch plane! if (sketchplane.Axis().Direction().IsParallel(gp_Dir(dir.x, dir.y, dir.z), Precision::Angular())) throw Base::ValueError("Rotation axis must not be perpendicular with the sketch plane"); return; } if (pcReferenceAxis->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) { if (subReferenceAxis.empty()) throw Base::ValueError("No rotation axis reference specified"); const Part::Feature* refFeature = static_cast<const Part::Feature*>(pcReferenceAxis); Part::TopoShape refShape = refFeature->Shape.getShape(); TopoDS_Shape ref = refShape.getSubShape(subReferenceAxis[0].c_str()); if (ref.ShapeType() == TopAbs_EDGE) { TopoDS_Edge refEdge = TopoDS::Edge(ref); if (refEdge.IsNull()) throw Base::ValueError("Failed to extract rotation edge"); BRepAdaptor_Curve adapt(refEdge); if (adapt.GetType() != GeomAbs_Line) throw Base::TypeError("Rotation edge must be a straight line"); gp_Pnt b = adapt.Line().Location(); base = Base::Vector3d(b.X(), b.Y(), b.Z()); gp_Dir d = adapt.Line().Direction(); dir = Base::Vector3d(d.X(), d.Y(), d.Z()); // Check that axis is co-planar with sketch plane! // Check that axis is perpendicular with sketch plane! if (sketchplane.Axis().Direction().IsParallel(d, Precision::Angular())) throw Base::ValueError("Rotation axis must not be perpendicular with the sketch plane"); return; } else { throw Base::TypeError("Rotation reference must be an edge"); } } throw Base::TypeError("Rotation axis reference is invalid"); }
PyObject* Application::sExport(PyObject * /*self*/, PyObject *args,PyObject * /*kwd*/) { PyObject* object; const char* filename; if (!PyArg_ParseTuple(args, "Os",&object,&filename)) return NULL; PY_TRY { App::Document* doc = 0; Py::List list(object); for (Py::List::iterator it = list.begin(); it != list.end(); ++it) { PyObject* item = (*it).ptr(); if (PyObject_TypeCheck(item, &(App::DocumentObjectPy::Type))) { App::DocumentObject* obj = static_cast<App::DocumentObjectPy*>(item)->getDocumentObjectPtr(); doc = obj->getDocument(); break; } } // get the view that belongs to the found document if (doc) { QString fileName = QString::fromUtf8(filename); QFileInfo fi; fi.setFile(fileName); QString ext = fi.completeSuffix().toLower(); if (ext == QLatin1String("iv") || ext == QLatin1String("wrl") || ext == QLatin1String("vrml") || ext == QLatin1String("wrz") || ext == QLatin1String("svg") || ext == QLatin1String("idtf")) { Gui::Document* gui_doc = Application::Instance->getDocument(doc); std::list<MDIView*> view3d = gui_doc->getMDIViewsOfType(View3DInventor::getClassTypeId()); if (view3d.empty()) { PyErr_SetString(PyExc_Exception, "Cannot export to SVG because document doesn't have a 3d view"); return 0; } else { QString cmd = QString::fromLatin1( "Gui.getDocument(\"%1\").mdiViewsOfType('Gui::View3DInventor')[0].dump(\"%2\")" ).arg(QLatin1String(doc->getName())).arg(fi.absoluteFilePath()); Base::Interpreter().runString(cmd.toUtf8()); } } else if (ext == QLatin1String("pdf")) { Gui::Document* gui_doc = Application::Instance->getDocument(doc); if (gui_doc) { Gui::MDIView* view = gui_doc->getActiveView(); if (view) { View3DInventor* view3d = qobject_cast<View3DInventor*>(view); if (view3d) view3d->viewAll(); QPrinter printer(QPrinter::ScreenResolution); printer.setOutputFormat(QPrinter::PdfFormat); printer.setOutputFileName(fileName); view->print(&printer); } } } } } PY_CATCH; Py_Return; }
App::DocumentObjectExecReturn *DrawViewSection::execute(void) { App::DocumentObject* link = Source.getValue(); App::DocumentObject* base = BaseView.getValue(); if (!link || !base) { Base::Console().Log("INFO - DVS::execute - No Source or Link - creation?\n"); return DrawView::execute(); } if (!link->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) return new App::DocumentObjectExecReturn("Source object is not a Part object"); if (!base->getTypeId().isDerivedFrom(TechDraw::DrawViewPart::getClassTypeId())) return new App::DocumentObjectExecReturn("BaseView object is not a DrawViewPart object"); //Base::Console().Message("TRACE - DVS::execute() - %s/%s\n",getNameInDocument(),Label.getValue()); const Part::TopoShape &partTopo = static_cast<Part::Feature*>(link)->Shape.getShape(); if (partTopo.getShape().IsNull()) return new App::DocumentObjectExecReturn("Linked shape object is empty"); (void) DrawView::execute(); //make sure Scale is up to date gp_Pln pln = getSectionPlane(); gp_Dir gpNormal = pln.Axis().Direction(); Base::Vector3d orgPnt = SectionOrigin.getValue(); Base::BoundBox3d bb = partTopo.getBoundBox(); if(!isReallyInBox(orgPnt, bb)) { Base::Console().Warning("DVS: Section Plane doesn't intersect part in %s\n",getNameInDocument()); Base::Console().Warning("DVS: Using center of bounding box.\n"); orgPnt = bb.GetCenter(); SectionOrigin.setValue(orgPnt); } // Make the extrusion face double dMax = bb.CalcDiagonalLength(); BRepBuilderAPI_MakeFace mkFace(pln, -dMax,dMax,-dMax,dMax); TopoDS_Face aProjFace = mkFace.Face(); if(aProjFace.IsNull()) return new App::DocumentObjectExecReturn("DrawViewSection - Projected face is NULL"); gp_Vec extrudeDir = dMax * gp_Vec(gpNormal); TopoDS_Shape prism = BRepPrimAPI_MakePrism(aProjFace, extrudeDir, false, true).Shape(); // We need to copy the shape to not modify the BRepstructure BRepBuilderAPI_Copy BuilderCopy(partTopo.getShape()); TopoDS_Shape myShape = BuilderCopy.Shape(); BRepAlgoAPI_Cut mkCut(myShape, prism); if (!mkCut.IsDone()) return new App::DocumentObjectExecReturn("Section cut has failed"); TopoDS_Shape rawShape = mkCut.Shape(); Bnd_Box testBox; BRepBndLib::Add(rawShape, testBox); testBox.SetGap(0.0); if (testBox.IsVoid()) { //prism & input don't intersect. rawShape is garbage, don't bother. Base::Console().Log("INFO - DVS::execute - prism & input don't intersect\n"); return DrawView::execute(); } gp_Pnt inputCenter; try { inputCenter = TechDrawGeometry::findCentroid(rawShape, Direction.getValue()); TopoDS_Shape mirroredShape = TechDrawGeometry::mirrorShape(rawShape, inputCenter, Scale.getValue()); geometryObject = buildGeometryObject(mirroredShape,inputCenter); //this is original shape after cut by section prism #if MOD_TECHDRAW_HANDLE_FACES extractFaces(); #endif //#if MOD_TECHDRAW_HANDLE_FACES } catch (Standard_Failure) { Handle_Standard_Failure e1 = Standard_Failure::Caught(); Base::Console().Log("LOG - DVS::execute - base shape failed for %s - %s **\n",getNameInDocument(),e1->GetMessageString()); return new App::DocumentObjectExecReturn(e1->GetMessageString()); } try { TopoDS_Compound sectionCompound = findSectionPlaneIntersections(rawShape); TopoDS_Shape mirroredSection = TechDrawGeometry::mirrorShape(sectionCompound, inputCenter, Scale.getValue()); TopoDS_Compound newFaces; BRep_Builder builder; builder.MakeCompound(newFaces); TopExp_Explorer expl(mirroredSection, TopAbs_FACE); for (; expl.More(); expl.Next()) { const TopoDS_Face& face = TopoDS::Face(expl.Current()); TopoDS_Face pFace = projectFace(face, inputCenter, Direction.getValue()); if (!pFace.IsNull()) { builder.Add(newFaces,pFace); } } sectionFaces = newFaces; } catch (Standard_Failure) { Handle_Standard_Failure e2 = Standard_Failure::Caught(); Base::Console().Log("LOG - DVS::execute - failed building section faces for %s - %s **\n",getNameInDocument(),e2->GetMessageString()); return new App::DocumentObjectExecReturn(e2->GetMessageString()); } return App::DocumentObject::StdReturn; }
App::DocumentObjectExecReturn *Sweep::execute(void) { if (Sections.getSize() == 0) return new App::DocumentObjectExecReturn("No sections linked."); App::DocumentObject* spine = Spine.getValue(); if (!(spine && spine->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId()))) return new App::DocumentObjectExecReturn("No spine linked."); const std::vector<std::string>& subedge = Spine.getSubValues(); TopoDS_Shape path; const Part::TopoShape& shape = static_cast<Part::Feature*>(spine)->Shape.getValue(); if (!shape._Shape.IsNull()) { try { if (!subedge.empty()) { BRepBuilderAPI_MakeWire mkWire; for (std::vector<std::string>::const_iterator it = subedge.begin(); it != subedge.end(); ++it) { TopoDS_Shape subshape = shape.getSubShape(it->c_str()); mkWire.Add(TopoDS::Edge(subshape)); } path = mkWire.Wire(); } else if (shape._Shape.ShapeType() == TopAbs_EDGE) { path = shape._Shape; } else if (shape._Shape.ShapeType() == TopAbs_WIRE) { BRepBuilderAPI_MakeWire mkWire(TopoDS::Wire(shape._Shape)); path = mkWire.Wire(); } else if (shape._Shape.ShapeType() == TopAbs_COMPOUND) { TopoDS_Iterator it(shape._Shape); for (; it.More(); it.Next()) { if (it.Value().IsNull()) return new App::DocumentObjectExecReturn("In valid element in spine."); if ((it.Value().ShapeType() != TopAbs_EDGE) && (it.Value().ShapeType() != TopAbs_WIRE)) { return new App::DocumentObjectExecReturn("Element in spine is neither an edge nor a wire."); } } Handle(TopTools_HSequenceOfShape) hEdges = new TopTools_HSequenceOfShape(); Handle(TopTools_HSequenceOfShape) hWires = new TopTools_HSequenceOfShape(); for (TopExp_Explorer xp(shape._Shape, TopAbs_EDGE); xp.More(); xp.Next()) hEdges->Append(xp.Current()); ShapeAnalysis_FreeBounds::ConnectEdgesToWires(hEdges, Precision::Confusion(), Standard_True, hWires); int len = hWires->Length(); if (len != 1) return new App::DocumentObjectExecReturn("Spine is not connected."); path = hWires->Value(1); } else { return new App::DocumentObjectExecReturn("Spine is neither an edge nor a wire."); } } catch (Standard_Failure) { return new App::DocumentObjectExecReturn("Invalid spine."); } } try { TopTools_ListOfShape profiles; const std::vector<App::DocumentObject*>& shapes = Sections.getValues(); std::vector<App::DocumentObject*>::const_iterator it; for (it = shapes.begin(); it != shapes.end(); ++it) { if (!(*it)->isDerivedFrom(Part::Feature::getClassTypeId())) return new App::DocumentObjectExecReturn("Linked object is not a shape."); TopoDS_Shape shape = static_cast<Part::Feature*>(*it)->Shape.getValue(); if (shape.IsNull()) return new App::DocumentObjectExecReturn("Linked shape is invalid."); // Extract first element of a compound if (shape.ShapeType() == TopAbs_COMPOUND) { TopoDS_Iterator it(shape); for (; it.More(); it.Next()) { if (!it.Value().IsNull()) { shape = it.Value(); break; } } } // There is a weird behaviour of BRepOffsetAPI_MakePipeShell when trying to add the wire as is. // If we re-create the wire then everything works fine. // http://forum.freecadweb.org/viewtopic.php?f=10&t=2673&sid=fbcd2ff4589f0b2f79ed899b0b990648#p20268 if (shape.ShapeType() == TopAbs_FACE) { TopoDS_Wire faceouterWire = ShapeAnalysis::OuterWire(TopoDS::Face(shape)); profiles.Append(faceouterWire); } else if (shape.ShapeType() == TopAbs_WIRE) { BRepBuilderAPI_MakeWire mkWire(TopoDS::Wire(shape)); profiles.Append(mkWire.Wire()); } else if (shape.ShapeType() == TopAbs_EDGE) { BRepBuilderAPI_MakeWire mkWire(TopoDS::Edge(shape)); profiles.Append(mkWire.Wire()); } else if (shape.ShapeType() == TopAbs_VERTEX) { profiles.Append(shape); } else { return new App::DocumentObjectExecReturn("Linked shape is not a vertex, edge, wire nor face."); } } Standard_Boolean isSolid = Solid.getValue() ? Standard_True : Standard_False; Standard_Boolean isFrenet = Frenet.getValue() ? Standard_True : Standard_False; BRepBuilderAPI_TransitionMode transMode; switch (Transition.getValue()) { case 1: transMode = BRepBuilderAPI_RightCorner; break; case 2: transMode = BRepBuilderAPI_RoundCorner; break; default: transMode = BRepBuilderAPI_Transformed; break; } if (path.ShapeType() == TopAbs_EDGE) { BRepBuilderAPI_MakeWire mkWire(TopoDS::Edge(path)); path = mkWire.Wire(); } BRepOffsetAPI_MakePipeShell mkPipeShell(TopoDS::Wire(path)); mkPipeShell.SetMode(isFrenet); mkPipeShell.SetTransitionMode(transMode); TopTools_ListIteratorOfListOfShape iter; for (iter.Initialize(profiles); iter.More(); iter.Next()) { mkPipeShell.Add(TopoDS_Shape(iter.Value())); } if (!mkPipeShell.IsReady()) Standard_Failure::Raise("shape is not ready to build"); mkPipeShell.Build(); if (isSolid) mkPipeShell.MakeSolid(); this->Shape.setValue(mkPipeShell.Shape()); return App::DocumentObject::StdReturn; } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); return new App::DocumentObjectExecReturn(e->GetMessageString()); } catch (...) { return new App::DocumentObjectExecReturn("A fatal error occurred when making the sweep"); } }
void CmdPartDesignBody::activated(int iMsg) { Q_UNUSED(iMsg); if ( !PartDesignGui::assureModernWorkflow( getDocument() ) ) return; App::Part *actPart = PartDesignGui::getActivePart (); App::Part* partOfBaseFeature = nullptr; std::vector<App::DocumentObject*> features = getSelection().getObjectsOfType(Part::Feature::getClassTypeId()); App::DocumentObject* baseFeature = nullptr; bool viewAll = features.empty(); if (!features.empty()) { if (features.size() == 1) { baseFeature = features[0]; if ( baseFeature->isDerivedFrom ( PartDesign::Feature::getClassTypeId() ) && PartDesign::Body::findBodyOf ( baseFeature ) ) { // Prevent creating bodies based on features already belonging to other bodies QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Bad base feature"), QObject::tr("Body can't be based on a PartDesign feature.")); baseFeature = nullptr; } else if (PartDesign::Body::findBodyOf ( baseFeature )){ QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Bad base feature"), QObject::tr("%1 already belongs to a body, can't use it as base feature for another body.") .arg(QString::fromUtf8(baseFeature->Label.getValue()))); baseFeature = nullptr; } else if ( baseFeature->isDerivedFrom ( Part::BodyBase::getClassTypeId() ) ) { // Prevent creating bodies based on bodies QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Bad base feature"), QObject::tr("Body can't be based on another body.")); baseFeature = nullptr; } else { partOfBaseFeature = App::Part::getPartOfObject(baseFeature); if (partOfBaseFeature != 0 && partOfBaseFeature != actPart){ //prevent cross-part mess QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Bad base feature"), QObject::tr("Base feature (%1) belongs to other part.") .arg(QString::fromUtf8(baseFeature->Label.getValue()))); baseFeature = nullptr; }; } } else { QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Bad base feature"), QObject::tr("Body may be based no more than on one feature.")); return; } } openCommand("Add a Body"); std::string bodyName = getUniqueObjectName("Body"); // add the Body feature itself, and make it active doCommand(Doc,"App.activeDocument().addObject('PartDesign::Body','%s')", bodyName.c_str()); if (baseFeature) { if (partOfBaseFeature){ //withdraw base feature from Part, otherwise visibility mandess results doCommand(Doc,"App.activeDocument().%s.removeObject(App.activeDocument().%s)", partOfBaseFeature->getNameInDocument(), baseFeature->getNameInDocument()); } doCommand(Doc,"App.activeDocument().%s.BaseFeature = App.activeDocument().%s", bodyName.c_str(), baseFeature->getNameInDocument()); } addModule(Gui,"PartDesignGui"); // import the Gui module only once a session doCommand(Gui::Command::Gui, "Gui.activeView().setActiveObject('%s', App.activeDocument().%s)", PDBODYKEY, bodyName.c_str()); // Make the "Create sketch" prompt appear in the task panel doCommand(Gui,"Gui.Selection.clearSelection()"); doCommand(Gui,"Gui.Selection.addSelection(App.ActiveDocument.%s)", bodyName.c_str()); if (actPart) { doCommand(Doc,"App.activeDocument().%s.addObject(App.ActiveDocument.%s)", actPart->getNameInDocument(), bodyName.c_str()); } // The method 'SoCamera::viewBoundingBox' is still declared as protected in Coin3d versions // older than 4.0. #if COIN_MAJOR_VERSION >= 4 // if no part feature was there then auto-adjust the camera if (viewAll) { Gui::Document* doc = Gui::Application::Instance->getDocument(getDocument()); Gui::View3DInventor* view = doc ? qobject_cast<Gui::View3DInventor*>(doc->getActiveView()) : nullptr; if (view) { SoCamera* camera = view->getViewer()->getCamera(); SbViewportRegion vpregion = view->getViewer()->getViewportRegion(); float aspectratio = vpregion.getViewportAspectRatio(); float size = Gui::ViewProviderOrigin::defaultSize(); SbBox3f bbox; bbox.setBounds(-size,-size,-size,size,size,size); camera->viewBoundingBox(bbox, aspectratio, 1.0f); } } #endif updateActive(); }
static PyObject * exporter(PyObject *self, PyObject *args) { PyObject* object; char* Name; if (!PyArg_ParseTuple(args, "Oet",&object,"utf-8",&Name)) return NULL; std::string EncodedName = std::string(Name); PyMem_Free(Name); Gui::WaitCursor wc; wc.restoreCursor(); PY_TRY { Py::Sequence objlist(object); if (objlist.size() == 0) Py_Error(Base::BaseExceptionFreeCADError, "No object to export"); std::string path = App::GetApplication().getHomePath(); path += "Mod/Path/PathScripts/"; QDir dir1(QString::fromUtf8(path.c_str()), QString::fromAscii("*_post.py")); std::string cMacroPath = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Macro") ->GetASCII("MacroPath",App::Application::getUserAppDataDir().c_str()); QDir dir2(QString::fromUtf8(cMacroPath.c_str()), QString::fromAscii("*_post.py")); QFileInfoList list = dir1.entryInfoList(); list << dir2.entryInfoList(); std::vector<std::string> scripts; for (int i = 0; i < list.size(); ++i) { QFileInfo fileInfo = list.at(i); scripts.push_back(fileInfo.baseName().toStdString()); } std::string selected; PathGui::DlgProcessorChooser Dlg(scripts); if (Dlg.exec() != QDialog::Accepted) { Py_Return; } selected = Dlg.getSelected(); std::ostringstream pre; std::ostringstream cmd; if (selected.empty()) { if (objlist.size() > 1) { Py_Error(Base::BaseExceptionFreeCADError, "Cannot export more than one object without using a post script"); } PyObject* item = objlist[0].ptr(); if (PyObject_TypeCheck(item, &(App::DocumentObjectPy::Type))) { App::DocumentObject* obj = static_cast<App::DocumentObjectPy*>(item)->getDocumentObjectPtr(); App::Document* doc = obj->getDocument(); Gui::Command::runCommand(Gui::Command::Gui,"import Path"); cmd << "Path.write(FreeCAD.getDocument(\"" << doc->getName() << "\").getObject(\"" << obj->getNameInDocument() << "\"),\"" << EncodedName << "\")"; Gui::Command::runCommand(Gui::Command::Gui,cmd.str().c_str()); } else { Py_Return; } } else { for (int i = 0; i < list.size(); ++i) { QFileInfo fileInfo = list.at(i); if (fileInfo.baseName().toStdString() == selected) { if (fileInfo.absoluteFilePath().contains(QString::fromAscii("PathScripts"))) { pre << "from PathScripts import " << selected; } else { pre << "import " << selected; } Gui::Command::runCommand(Gui::Command::Gui,pre.str().c_str()); cmd << selected << ".export(__objs__,\"" << EncodedName << "\")"; Gui::Command::runCommand(Gui::Command::Gui,cmd.str().c_str()); } } } } PY_CATCH; Py_Return; }
PyObject* Application::sInsert(PyObject * /*self*/, PyObject *args,PyObject * /*kwd*/) { char* Name; char* DocName=0; if (!PyArg_ParseTuple(args, "et|s","utf-8",&Name,&DocName)) return NULL; std::string Utf8Name = std::string(Name); PyMem_Free(Name); PY_TRY { QString fileName = QString::fromUtf8(Utf8Name.c_str()); QFileInfo fi; fi.setFile(fileName); QString ext = fi.suffix().toLower(); if (ext == QLatin1String("iv")) { App::Document *doc = 0; if (DocName) doc = App::GetApplication().getDocument(DocName); else doc = App::GetApplication().getActiveDocument(); if (!doc) doc = App::GetApplication().newDocument(DocName); App::DocumentObject* obj = doc->addObject("App::InventorObject", (const char*)fi.baseName().toUtf8()); obj->Label.setValue((const char*)fi.baseName().toUtf8()); static_cast<App::PropertyString*>(obj->getPropertyByName("FileName")) ->setValue((const char*)fi.absoluteFilePath().toUtf8()); doc->recompute(); } else if (ext == QLatin1String("wrl") || ext == QLatin1String("vrml") || ext == QLatin1String("wrz")) { App::Document *doc = 0; if (DocName) doc = App::GetApplication().getDocument(DocName); else doc = App::GetApplication().getActiveDocument(); if (!doc) doc = App::GetApplication().newDocument(DocName); App::DocumentObject* obj = doc->addObject("App::VRMLObject", (const char*)fi.baseName().toUtf8()); obj->Label.setValue((const char*)fi.baseName().toUtf8()); static_cast<App::PropertyFileIncluded*>(obj->getPropertyByName("VrmlFile")) ->setValue((const char*)fi.absoluteFilePath().toUtf8()); doc->recompute(); } else if (ext == QLatin1String("py") || ext == QLatin1String("fcmacro") || ext == QLatin1String("fcscript")) { PythonEditor* editor = new PythonEditor(); editor->setWindowIcon(Gui::BitmapFactory().pixmap("applications-python")); PythonEditorView* edit = new PythonEditorView(editor, getMainWindow()); edit->open(fileName); edit->resize(400, 300); getMainWindow()->addWindow( edit ); } else { Base::Console().Error("File type '%s' not supported\n", ext.toLatin1().constData()); } } PY_CATCH; Py_Return; }
Py::Object exporter(const Py::Tuple& args) { PyObject *object; char *Name; if (!PyArg_ParseTuple(args.ptr(), "Oet", &object, "utf-8", &Name)) throw Py::Exception(); std::string encodedName = std::string(Name); PyMem_Free(Name); Base::FileInfo file(encodedName); // extract ending if (file.extension().empty()) throw Py::RuntimeError("No file extension"); Py::Sequence list(object); Base::Type pointsId = Base::Type::fromName("Points::Feature"); for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) { PyObject* item = (*it).ptr(); if (PyObject_TypeCheck(item, &(App::DocumentObjectPy::Type))) { App::DocumentObject* obj = static_cast<App::DocumentObjectPy*>(item)->getDocumentObjectPtr(); if (obj->getTypeId().isDerivedFrom(pointsId)) { Points::Feature* fea = static_cast<Points::Feature*>(obj); const PointKernel& kernel = fea->Points.getValue(); std::unique_ptr<Writer> writer; if (file.hasExtension("asc")) { writer.reset(new AscWriter(kernel)); } #ifdef HAVE_PCL_IO else if (file.hasExtension("ply")) { writer.reset(new PlyWriter(kernel)); } else if (file.hasExtension("pcd")) { writer.reset(new PcdWriter(kernel)); } #endif else { throw Py::RuntimeError("Unsupported file extension"); } // get additional properties if there App::PropertyInteger* width = dynamic_cast<App::PropertyInteger*> (fea->getPropertyByName("Width")); if (width) { writer->setWidth(width->getValue()); } App::PropertyInteger* height = dynamic_cast<App::PropertyInteger*> (fea->getPropertyByName("Height")); if (height) { writer->setHeight(height->getValue()); } // get gray values Points::PropertyGreyValueList* grey = dynamic_cast<Points::PropertyGreyValueList*> (fea->getPropertyByName("Intensity")); if (grey) { writer->setIntensities(grey->getValues()); } // get colors App::PropertyColorList* col = dynamic_cast<App::PropertyColorList*> (fea->getPropertyByName("Color")); if (col) { writer->setColors(col->getValues()); } // get normals Points::PropertyNormalList* nor = dynamic_cast<Points::PropertyNormalList*> (fea->getPropertyByName("Normal")); if (nor) { writer->setNormals(nor->getValues()); } writer->write(encodedName); break; } else { Base::Console().Message("'%s' is not a point object, export will be ignored.\n", obj->Label.getValue()); } } } return Py::None(); }
void DlgExtrusion::writeParametersToFeature(App::DocumentObject &feature, App::DocumentObject* base) const { Gui::Command::doCommand(Gui::Command::Doc,"f = App.getDocument('%s').getObject('%s')", feature.getDocument()->getName(), feature.getNameInDocument()); if (base) Gui::Command::doCommand(Gui::Command::Doc,"f.Base = App.getDocument('%s').getObject('%s')", base->getDocument()->getName(), base->getNameInDocument()); Part::Extrusion::eDirMode dirMode = this->getDirMode(); const char* modestr = Part::Extrusion::eDirModeStrings[dirMode]; Gui::Command::doCommand(Gui::Command::Doc,"f.DirMode = \"%s\"", modestr); if (dirMode == Part::Extrusion::dmCustom){ Base::Vector3d dir = this->getDir(); Gui::Command::doCommand(Gui::Command::Doc, "f.Dir = App.Vector(%.15f, %.15f, %.15f)", dir.x, dir.y, dir.z); } App::PropertyLinkSub lnk; this->getAxisLink(lnk); std::stringstream linkstr; if(lnk.getValue() == nullptr){ linkstr << "None"; } else { linkstr << "(App.getDocument(\"" << lnk.getValue()->getDocument()->getName() <<"\")." << lnk.getValue()->getNameInDocument(); linkstr << ", ["; for (const std::string &str: lnk.getSubValues()){ linkstr << "\"" << str << "\""; } linkstr << "])"; } Gui::Command::doCommand(Gui::Command::Doc,"f.DirLink = %s", linkstr.str().c_str()); Gui::Command::doCommand(Gui::Command::Doc,"f.LengthFwd = %.15f", ui->spinLenFwd->value().getValue()); Gui::Command::doCommand(Gui::Command::Doc,"f.LengthRev = %.15f", ui->spinLenRev->value().getValue()); Gui::Command::doCommand(Gui::Command::Doc,"f.Solid = %s", ui->chkSolid->isChecked() ? "True" : "False"); Gui::Command::doCommand(Gui::Command::Doc,"f.Reversed = %s", ui->chkReversed->isChecked() ? "True" : "False"); Gui::Command::doCommand(Gui::Command::Doc,"f.Symmetric = %s", ui->chkSymmetric->isChecked() ? "True" : "False"); Gui::Command::doCommand(Gui::Command::Doc,"f.TaperAngle = %.15f", ui->spinTaperAngle->value().getValue()); Gui::Command::doCommand(Gui::Command::Doc,"f.TaperAngleRev = %.15f", ui->spinTaperAngleRev->value().getValue()); }