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);
}
Exemple #2
0
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");
}
Exemple #5
0
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());
    }
Exemple #7
0
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());
    }
}
Exemple #9
0
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();
}
Exemple #10
0
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;
}
Exemple #13
0
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;
}
Exemple #15
0
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());
    }
}
Exemple #16
0
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;
}
Exemple #17
0
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;
}
Exemple #22
0
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");
    }
}
Exemple #26
0
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;
}
Exemple #29
0
    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();
    }
Exemple #30
0
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());
}