TopLoc_Location Feature::getLocation() const
{
    Base::Placement pl = this->Placement.getValue();
    Base::Rotation rot(pl.getRotation());
    Base::Vector3d axis;
    double angle;
    rot.getValue(axis, angle);
    gp_Trsf trf;
    trf.SetRotation(gp_Ax1(gp_Pnt(), gp_Dir(axis.x, axis.y, axis.z)), angle);
    trf.SetTranslationPart(gp_Vec(pl.getPosition().x,pl.getPosition().y,pl.getPosition().z));
    return TopLoc_Location(trf);
}
void TaskDatumParameters::updateSuperplacementUI()
{
    Part::Datum* pcDatum = static_cast<Part::Datum*>(DatumView->getObject());
    Base::Placement pl = pcDatum->superPlacement.getValue();
    Base::Vector3d pos = pl.getPosition();
    Base::Rotation rot = pl.getRotation();
    double yaw, pitch, roll;
    rot.getYawPitchRoll(yaw, pitch, roll);

    bool bBlock = true;
    ui->superplacementX->blockSignals(bBlock);
    ui->superplacementY->blockSignals(bBlock);
    ui->superplacementZ->blockSignals(bBlock);
    ui->superplacementYaw->blockSignals(bBlock);
    ui->superplacementPitch->blockSignals(bBlock);
    ui->superplacementRoll->blockSignals(bBlock);

    ui->superplacementX->setValue(Base::Quantity(pos.x,Base::Unit::Length));
    ui->superplacementY->setValue(Base::Quantity(pos.y,Base::Unit::Length));
    ui->superplacementZ->setValue(Base::Quantity(pos.z,Base::Unit::Length));
    ui->superplacementYaw->setValue(yaw);
    ui->superplacementPitch->setValue(pitch);
    ui->superplacementRoll->setValue(roll);

    auto expressions = pcDatum->ExpressionEngine.getExpressions();
    bool bRotationBound = false;
    bRotationBound = bRotationBound ||
            expressions.find(App::ObjectIdentifier::parse(pcDatum,std::string("superPlacement.Rotation.Angle"))) != expressions.end();
    bRotationBound = bRotationBound ||
            expressions.find(App::ObjectIdentifier::parse(pcDatum,std::string("superPlacement.Rotation.Axis.x"))) != expressions.end();
    bRotationBound = bRotationBound ||
            expressions.find(App::ObjectIdentifier::parse(pcDatum,std::string("superPlacement.Rotation.Axis.y"))) != expressions.end();
    bRotationBound = bRotationBound ||
            expressions.find(App::ObjectIdentifier::parse(pcDatum,std::string("superPlacement.Rotation.Axis.z"))) != expressions.end();

    ui->superplacementYaw->setEnabled(!bRotationBound);
    ui->superplacementPitch->setEnabled(!bRotationBound);
    ui->superplacementRoll->setEnabled(!bRotationBound);

    QString tooltip = bRotationBound ? tr("Not editable because rotation part of superplacement is bound by expressions.") : QString();
    ui->superplacementYaw->setToolTip(tooltip);
    ui->superplacementPitch->setToolTip(tooltip);
    ui->superplacementRoll->setToolTip(tooltip);

    bBlock = false;
    ui->superplacementX->blockSignals(bBlock);
    ui->superplacementY->blockSignals(bBlock);
    ui->superplacementZ->blockSignals(bBlock);
    ui->superplacementYaw->blockSignals(bBlock);
    ui->superplacementPitch->blockSignals(bBlock);
    ui->superplacementRoll->blockSignals(bBlock);
}
void ViewProviderDragger::updateTransform(const Base::Placement& from, SoTransform* to)
{
  float q0 = (float)from.getRotation().getValue()[0];
  float q1 = (float)from.getRotation().getValue()[1];
  float q2 = (float)from.getRotation().getValue()[2];
  float q3 = (float)from.getRotation().getValue()[3];
  float px = (float)from.getPosition().x;
  float py = (float)from.getPosition().y;
  float pz = (float)from.getPosition().z;
  to->rotation.setValue(q0,q1,q2,q3);
  to->translation.setValue(px,py,pz);
  to->center.setValue(0.0f,0.0f,0.0f);
  to->scaleFactor.setValue(1.0f,1.0f,1.0f);
}
void CmdRobotSetDefaultOrientation::activated(int iMsg)
{
    // create placement dialog 
    Gui::Dialog::Placement *Dlg = new Gui::Dialog::Placement();
    Base::Placement place;
    Dlg->setPlacement(place);
    if(Dlg->exec() == QDialog::Accepted ){
        place = Dlg->getPlacement();
        Base::Rotation rot = place.getRotation();
        Base::Vector3d disp = place.getPosition();
        doCommand(Doc,"_DefOrientation = FreeCAD.Rotation(%f,%f,%f,%f)",rot[0],rot[1],rot[2],rot[3]);
        doCommand(Doc,"_DefDisplacement = FreeCAD.Vector(%f,%f,%f)",disp[0],disp[1],disp[2]);
    }
      
}
void CmdPointsTransform::activated(int iMsg)
{
    // This is a test command to transform a point cloud directly written in C++ (not Python)
    Base::Placement trans;
    trans.setRotation(Base::Rotation(Base::Vector3d(0.0, 0.0, 1.0), 1.570796));

    openCommand("Transform points");
    //std::vector<App::DocumentObject*> points = getSelection().getObjectsOfType(Points::Feature::getClassTypeId());
    //for (std::vector<App::DocumentObject*>::const_iterator it = points.begin(); it != points.end(); ++it) {
    //    Base::Placement p = static_cast<Points::Feature*>(*it)->Placement.getValue();
    //    p._rot *= Base::Rotation(Base::Vector3d(0.0, 0.0, 1.0), 1.570796);
    //    static_cast<Points::Feature*>(*it)->Placement.setValue(p);
    //}
    commitCommand();
}
void TaskRobot6Axis::viewTool(const Base::Placement pos)
{
    double A,B,C;
    pos.getRotation().getYawPitchRoll(A,B,C);

    QString result = QString::fromAscii("Tool:( %1, %2, %3, %4, %5, %6 )")
        .arg(Base::UnitsApi::toDblWithUserPrefs(Base::Length,pos.getPosition().x),0,'f',1)
        .arg(Base::UnitsApi::toDblWithUserPrefs(Base::Length,pos.getPosition().y),0,'f',1)
        .arg(Base::UnitsApi::toDblWithUserPrefs(Base::Length,pos.getPosition().z),0,'f',1)
        .arg(Base::UnitsApi::toDblWithUserPrefs(Base::Angle,A),0,'f',1)
        .arg(Base::UnitsApi::toDblWithUserPrefs(Base::Angle,B),0,'f',1)
        .arg(Base::UnitsApi::toDblWithUserPrefs(Base::Angle,C),0,'f',1);

    ui->label_Tool->setText(result);
}
Exemple #7
0
void Feature::onChanged(const App::Property* prop)
{
    // if the placement has changed apply the change to the point data as well
    if (prop == &this->Placement) {
        PointKernel& pts = const_cast<PointKernel&>(this->Points.getValue());
        pts.setTransform(this->Placement.getValue().toMatrix());
    }
    // if the point data has changed check and adjust the transformation as well
    else if (prop == &this->Points) {
        Base::Placement p;
        p.fromMatrix(this->Points.getValue().getTransform());
        if (p != this->Placement.getValue())
            this->Placement.setValue(p);
    }
    
    GeoFeature::onChanged(prop);
}
PyObject* FemMeshPy::setTransform(PyObject *args)
{
    PyObject* ptr;
    if (!PyArg_ParseTuple(args, "O!", &(Base::PlacementPy::Type), &ptr))
        return 0;

    try {
        Base::Placement* placement = static_cast<Base::PlacementPy*>(ptr)->getPlacementPtr();
        Base::Matrix4D mat = placement->toMatrix();
        getFemMeshPtr()->transformGeometry(mat);
    }
    catch (const std::exception& e) {
        PyErr_SetString(PyExc_Exception, e.what());
        return 0;
    }
    Py_Return;
}
PyObject* GeometryPy::rotate(PyObject *args)
{
    PyObject* o;
    if (!PyArg_ParseTuple(args, "O!", &(Base::PlacementPy::Type),&o))
        return 0;

    Base::Placement* plm = static_cast<Base::PlacementPy*>(o)->getPlacementPtr();
    Base::Rotation rot(plm->getRotation());
    Base::Vector3d pnt, dir;
    double angle;

    rot.getValue(dir, angle);
    pnt = plm->getPosition();
    
    gp_Ax1 ax1(gp_Pnt(pnt.x,pnt.y,pnt.z), gp_Dir(dir.x,dir.y,dir.z));
    getGeometryPtr()->handle()->Rotate(ax1, angle);
    Py_Return;
}
void Placement::setPlacementData(const Base::Placement& p)
{
    signalMapper->blockSignals(true);
    ui->xPos->setValue(Base::Quantity(p.getPosition().x, Base::Unit::Length));
    ui->yPos->setValue(Base::Quantity(p.getPosition().y, Base::Unit::Length));
    ui->zPos->setValue(Base::Quantity(p.getPosition().z, Base::Unit::Length));

    double Y,P,R;
    p.getRotation().getYawPitchRoll(Y,P,R);
    ui->yawAngle->setValue(Base::Quantity(Y, Base::Unit::Angle));
    ui->pitchAngle->setValue(Base::Quantity(P, Base::Unit::Angle));
    ui->rollAngle->setValue(Base::Quantity(R, Base::Unit::Angle));

    // check if the user-defined direction is already there
    bool newitem = true;
    double angle;
    Base::Vector3d axis;
    p.getRotation().getValue(axis, angle);
    ui->angle->setValue(Base::Quantity(angle*180.0/D_PI, Base::Unit::Angle));
    Base::Vector3d dir(axis.x,axis.y,axis.z);
    for (int i=0; i<ui->direction->count()-1; i++) {
        QVariant data = ui->direction->itemData (i);
        if (data.canConvert<Base::Vector3d>()) {
            const Base::Vector3d val = data.value<Base::Vector3d>();
            if (val == dir) {
                ui->direction->setCurrentIndex(i);
                newitem = false;
                break;
            }
        }
    }

    if (newitem) {
        // add a new item before the very last item
        QString display = QString::fromAscii("(%1,%2,%3)")
            .arg(dir.x)
            .arg(dir.y)
            .arg(dir.z);
        ui->direction->insertItem(ui->direction->count()-1, display,
            QVariant::fromValue<Base::Vector3d>(dir));
        ui->direction->setCurrentIndex(ui->direction->count()-2);
    }
    signalMapper->blockSignals(false);
}
void ViewProviderRobotObject::DraggerMotionCallback(SoDragger *dragger)
{
    float q0, q1, q2, q3;

    Robot::RobotObject* robObj = static_cast<Robot::RobotObject*>(pcObject);
    Base::Placement Tcp = robObj->Tcp.getValue();
    const SbMatrix & M = dragger->getMotionMatrix ();
    SbVec3f    translation;
    SbRotation rotation;
    SbVec3f    scaleFactor;
    SbRotation scaleOrientation;
    SbVec3f    center(Tcp.getPosition().x,Tcp.getPosition().y,Tcp.getPosition().z);
    M.getTransform(translation, rotation, scaleFactor, scaleOrientation);
    rotation.getValue(q0, q1, q2, q3);
    //Base::Console().Message("M %f %f %f\n", M[3][0], M[3][1], M[3][2]);
    Base::Rotation rot(q0, q1, q2, q3);
    Base::Vector3d pos(translation[0],translation[1],translation[2]);
    robObj->Tcp.setValue(Base::Placement(pos,rot));
}
Exemple #12
0
void TransformStrategy::resetViewTransform(App::DocumentObject* obj)
{
    Gui::Document* doc = Gui::Application::Instance->getDocument(obj->getDocument());
    std::map<std::string,App::Property*> props;
    obj->getPropertyMap(props);
    // search for the placement property
    std::map<std::string,App::Property*>::iterator jt;
    jt = std::find_if(props.begin(), props.end(), find_transform());
    if (jt != props.end()) {
        Base::Placement local = static_cast<App::PropertyPlacement*>(jt->second)->getValue();
        Gui::ViewProvider* vp = doc->getViewProvider(obj);
        if (vp) vp->setTransformation(local.toMatrix());
    }
    else {
        // No placement found
        Gui::ViewProvider* vp = doc->getViewProvider(obj);
        if (vp) vp->setTransformation(Base::Matrix4D());
    }
}
Exemple #13
0
void TransformStrategy::applyViewTransform(const Base::Placement& plm, App::DocumentObject* obj)
{
    Gui::Document* doc = Gui::Application::Instance->getDocument(obj->getDocument());
    std::map<std::string,App::Property*> props;
    obj->getPropertyMap(props);
    // search for the placement property
    std::map<std::string,App::Property*>::iterator jt;
    jt = std::find_if(props.begin(), props.end(), find_placement());
    if (jt != props.end()) {
        Base::Placement local = static_cast<App::PropertyPlacement*>(jt->second)->getValue();
        local *= plm; // in case a placement is already set
        Gui::ViewProvider* vp = doc->getViewProvider(obj);
        if (vp) vp->setTransformation(local.toMatrix());
    }
    else {
        // No placement found, so apply the transformation directly
        Gui::ViewProvider* vp = doc->getViewProvider(obj);
        if (vp) vp->setTransformation(plm.toMatrix());
    }
}
Exemple #14
0
void Transform::on_applyButton_clicked()
{
    Gui::WaitCursor wc;
    Base::Placement plm = this->getPlacementData();
    Base::Matrix4D mat = plm.toMatrix();
    strategy->commitTransform(mat);

    // nullify the values
    QList<Gui::QuantitySpinBox*> sb = this->findChildren<Gui::QuantitySpinBox*>();
    for (QList<Gui::QuantitySpinBox*>::iterator it = sb.begin(); it != sb.end(); ++it) {
        (*it)->blockSignals(true);
        (*it)->setValue(0.0);
        (*it)->blockSignals(false);
    }

    Base::Vector3d cnt = strategy->getRotationCenter();
    ui->xCnt->setValue(Base::Quantity(cnt.x, Base::Unit::Length));
    ui->yCnt->setValue(Base::Quantity(cnt.y, Base::Unit::Length));
    ui->zCnt->setValue(Base::Quantity(cnt.z, Base::Unit::Length));
}
void ViewProvider2DObject::updateData(const App::Property* prop)
{
    ViewProviderPart::updateData(prop);

    if (prop->getTypeId() == Part::PropertyPartShape::getClassTypeId()) {
        Base::BoundBox3d bbox = static_cast<const Part::PropertyPartShape*>(prop)->getBoundingBox();
        if (!bbox.IsValid()) return;
        GridRoot->removeAllChildren();
        Base::Placement place = static_cast<const Part::PropertyPartShape*>(prop)->getComplexData()->getPlacement();
        place.invert();
        Base::ViewProjMatrix proj(place.toMatrix());
        Base::BoundBox2D bbox2d = bbox.ProjectBox(&proj);
        this->MinX = bbox2d.fMinX;
        this->MaxX = bbox2d.fMaxX;
        this->MinY = bbox2d.fMinY;
        this->MaxY = bbox2d.fMaxY;
        if (ShowGrid.getValue()) {
            createGrid();
        }
    }
}
void TaskDatumParameters::onSuperplacementChanged(double /*val*/, int idx)
{
    Part::Datum* pcDatum = static_cast<Part::Datum*>(DatumView->getObject());
    Base::Placement pl = pcDatum->superPlacement.getValue();

    Base::Vector3d pos = pl.getPosition();
    if (idx == 0) {
        pos.x = ui->superplacementX->value().getValueAs(Base::Quantity::MilliMetre);
    }
    if (idx == 1) {
        pos.y = ui->superplacementY->value().getValueAs(Base::Quantity::MilliMetre);
    }
    if (idx == 2) {
        pos.z = ui->superplacementZ->value().getValueAs(Base::Quantity::MilliMetre);
    }
    if (idx >= 0  && idx <= 2){
        pl.setPosition(pos);
    }

    Base::Rotation rot = pl.getRotation();
    double yaw, pitch, roll;
    rot.getYawPitchRoll(yaw, pitch, roll);
    if (idx == 3) {
        yaw = ui->superplacementYaw->value().getValueAs(Base::Quantity::Degree);
    }
    if (idx == 4) {
        pitch = ui->superplacementPitch->value().getValueAs(Base::Quantity::Degree);
    }
    if (idx == 5) {
        roll = ui->superplacementRoll->value().getValueAs(Base::Quantity::Degree);
    }
    if (idx >= 3  &&  idx <= 5){
        rot.setYawPitchRoll(yaw,pitch,roll);
        pl.setRotation(rot);
    }

    pcDatum->superPlacement.setValue(pl);
    updatePreview();
}
Exemple #17
0
void Feature::onChanged(const App::Property* prop)
{
    // if the placement has changed apply the change to the mesh data as well
    if (prop == &this->Placement) {
        MeshObject& mesh = const_cast<MeshObject&>(this->Mesh.getValue());
        mesh.setTransform(this->Placement.getValue().toMatrix());
    }
    // if the mesh data has changed check and adjust the transformation as well
    else if (prop == &this->Mesh) {
        Base::Placement p;
        p.fromMatrix(this->Mesh.getValue().getTransform());
        if (p != this->Placement.getValue())
            this->Placement.setValue(p);
    }

    // Note: If the Mesh property has changed the property and this object are marked as 'touched'
    // but no recomputation of this objects needs to be done because the Mesh property is regarded
    // as output of a previous recomputation The mustExecute() method returns 0 in that case. 
    // However, objects that reference this object the Mesh property can be an input parameter.
    // As this object and the property are touched such objects can check this and return a value 1 
    // (or -1) in their mustExecute() to be recomputed the next time the document recomputes itself.
    DocumentObject::onChanged(prop);
}
void Placement::revertTransformation()
{
    for (std::set<std::string>::iterator it = documents.begin(); it != documents.end(); ++it) {
        Gui::Document* document = Application::Instance->getDocument(it->c_str());
        if (!document) continue;

        std::vector<App::DocumentObject*> obj = document->getDocument()->
            getObjectsOfType(App::DocumentObject::getClassTypeId());
        if (!obj.empty()) {
            for (std::vector<App::DocumentObject*>::iterator it=obj.begin();it!=obj.end();++it) {
                std::map<std::string,App::Property*> props;
                (*it)->getPropertyMap(props);
                // search for the placement property
                std::map<std::string,App::Property*>::iterator jt;
                jt = std::find_if(props.begin(), props.end(), find_placement(this->propertyName));
                if (jt != props.end()) {
                    Base::Placement cur = static_cast<App::PropertyPlacement*>(jt->second)->getValue();
                    Gui::ViewProvider* vp = document->getViewProvider(*it);
                    if (vp) vp->setTransformation(cur.toMatrix());
                }
            }
        }
    }
}
bool Revolution::suggestReversed(void)
{
    try {
        updateAxis();

        Part::Part2DObject* sketch = getVerifiedSketch();
        std::vector<TopoDS_Wire> wires = getSketchWires();
        TopoDS_Shape sketchshape = makeFace(wires);

        Base::Vector3d b = Base.getValue();
        Base::Vector3d v = Axis.getValue();

        // get centre of gravity of the sketch face
        GProp_GProps props;
        BRepGProp::SurfaceProperties(sketchshape, props);
        gp_Pnt cog = props.CentreOfMass();
        Base::Vector3d p_cog(cog.X(), cog.Y(), cog.Z());
        // get direction to cog from its projection on the revolve axis
        Base::Vector3d perp_dir = p_cog - p_cog.Perpendicular(b, v);
        // get cross product of projection direction with revolve axis direction
        Base::Vector3d cross = v % perp_dir;
        // get sketch vector pointing away from support material
        Base::Placement SketchPos = sketch->Placement.getValue();
        Base::Rotation SketchOrientation = SketchPos.getRotation();
        Base::Vector3d SketchNormal(0,0,1);
        SketchOrientation.multVec(SketchNormal,SketchNormal);
        // simply convert double to float
        Base::Vector3d norm(SketchNormal.x, SketchNormal.y, SketchNormal.z);

        // return true if the angle between norm and cross is obtuse
        return norm * cross < 0.f;
    }
    catch (...) {
        return Reversed.getValue();
    }
}
void ViewProviderRobotObject::setDragger()
{
    assert(pcDragger==0);
    pcDragger = new SoJackDragger();
    pcDragger->addMotionCallback(sDraggerMotionCallback,this);
    pcTcpRoot->addChild(pcDragger);

    // set the actual TCP position
    Robot::RobotObject* robObj = static_cast<Robot::RobotObject*>(pcObject);
    Base::Placement loc = robObj->Tcp.getValue();
    SbMatrix  M;
    M.setTransform(SbVec3f(loc.getPosition().x,loc.getPosition().y,loc.getPosition().z),
                   SbRotation(loc.getRotation()[0],loc.getRotation()[1],loc.getRotation()[2],loc.getRotation()[3]),
                   SbVec3f(150,150,150)
                   );
    pcDragger->setMotionMatrix(M);


}
void ViewProviderVRMLObject::updateData(const App::Property* prop)
{
    App::VRMLObject* ivObj = static_cast<App::VRMLObject*>(pcObject);
    if (prop == &ivObj->VrmlFile) {
        // read also from file
        const char* filename = ivObj->VrmlFile.getValue();
        QString fn = QString::fromUtf8(filename);
        QFile file(fn);
        SoInput in;
        pcVRML->removeAllChildren();
        if (!fn.isEmpty() && file.open(QFile::ReadOnly)) {
            QFileInfo fi(fn);
            QByteArray filepath = fi.absolutePath().toUtf8();
            QByteArray subpath = filepath + "/" + ivObj->getNameInDocument();

            // Add this to the search path in order to read inline files
            SoInput::addDirectoryFirst(filepath.constData());
            SoInput::addDirectoryFirst(subpath.constData());

            // Read in the file
            QByteArray buffer = file.readAll();
            in.setBuffer((void *)buffer.constData(), buffer.length());
            SoSeparator * node = SoDB::readAll(&in);

            if (node) {
                pcVRML->addChild(node);

                std::list<std::string> urls;
                getLocalResources(node, urls);
                if (!urls.empty() && ivObj->Urls.getSize() == 0) {
                    std::vector<std::string> res;
                    res.insert(res.end(), urls.begin(), urls.end());
                    ivObj->Urls.setValues(res);
                }
            }
            SoInput::removeDirectory(filepath.constData());
            SoInput::removeDirectory(subpath.constData());
        }
    }
    else if (prop->isDerivedFrom(App::PropertyPlacement::getClassTypeId()) &&
             strcmp(prop->getName(), "Placement") == 0) {
        // Note: If R is the rotation, c the rotation center and t the translation
        // vector then Inventor applies the following transformation: R*(x-c)+c+t
        // In FreeCAD a placement only has a rotation and a translation part but
        // no rotation center. This means that the following equation must be ful-
        // filled: R * (x-c) + c + t = R * x + t
        //    <==> R * x + t - R * c + c = R * x + t
        //    <==> (I-R) * c = 0 ==> c = 0
        // This means that the center point must be the origin!
        Base::Placement p = static_cast<const App::PropertyPlacement*>(prop)->getValue();
        float q0 = (float)p.getRotation().getValue()[0];
        float q1 = (float)p.getRotation().getValue()[1];
        float q2 = (float)p.getRotation().getValue()[2];
        float q3 = (float)p.getRotation().getValue()[3];
        float px = (float)p.getPosition().x;
        float py = (float)p.getPosition().y;
        float pz = (float)p.getPosition().z;
        pcTransform->rotation.setValue(q0,q1,q2,q3);
        pcTransform->translation.setValue(px,py,pz);
        pcTransform->center.setValue(0.0f,0.0f,0.0f);
        pcTransform->scaleFactor.setValue(1.0f,1.0f,1.0f);
    }
}
Exemple #22
0
 Py::Object fromShape(const Py::Tuple& args)
 {
     PyObject *pcObj;
     if (!PyArg_ParseTuple(args.ptr(), "O", &pcObj))
         throw Py::Exception();
     TopoDS_Shape shape;
     try {
         if (PyObject_TypeCheck(pcObj, &(Part::TopoShapePy::Type))) {
             shape = static_cast<Part::TopoShapePy*>(pcObj)->getTopoShapePtr()->getShape();
         } else {
             throw Py::TypeError("the given object is not a shape");
         }
         if (!shape.IsNull()) {
             if (shape.ShapeType() == TopAbs_WIRE) {
                 Path::Toolpath result;
                 bool first = true;
                 Base::Placement last;
                 
                 TopExp_Explorer ExpEdges (shape,TopAbs_EDGE);
                 while (ExpEdges.More()) {
                     const TopoDS_Edge& edge = TopoDS::Edge(ExpEdges.Current());
                     TopExp_Explorer ExpVerts(edge,TopAbs_VERTEX);
                     bool vfirst = true;
                     while (ExpVerts.More()) {
                         const TopoDS_Vertex& vert = TopoDS::Vertex(ExpVerts.Current());
                         gp_Pnt pnt = BRep_Tool::Pnt(vert);
                         Base::Placement tpl;
                         tpl.setPosition(Base::Vector3d(pnt.X(),pnt.Y(),pnt.Z()));
                         if (first) {
                             // add first point as a G0 move
                             Path::Command cmd;
                             std::ostringstream ctxt;
                             ctxt << "G0 X" << tpl.getPosition().x << " Y" << tpl.getPosition().y << " Z" << tpl.getPosition().z;
                             cmd.setFromGCode(ctxt.str());
                             result.addCommand(cmd);
                             first = false;
                             vfirst = false;
                         } else {
                             if (vfirst)
                                 vfirst = false;
                             else {
                                 Path::Command cmd;
                                 cmd.setFromPlacement(tpl);
                     
                                 // write arc data if needed
                                 BRepAdaptor_Curve adapt(edge);
                                 if (adapt.GetType() == GeomAbs_Circle) {
                                     gp_Circ circ = adapt.Circle();
                                     gp_Pnt c = circ.Location();
                                     bool clockwise = false;
                                     gp_Dir n = circ.Axis().Direction();
                                     if (n.Z() < 0)
                                         clockwise = true;
                                     Base::Vector3d center = Base::Vector3d(c.X(),c.Y(),c.Z());
                                     // center coords must be relative to last point
                                     center -= last.getPosition();
                                     cmd.setCenter(center,clockwise);
                                 }
                                 result.addCommand(cmd);
                             }
                         }
                         ExpVerts.Next();
                         last = tpl;
                     }
                     ExpEdges.Next();
                 }
                 return Py::asObject(new PathPy(new Path::Toolpath(result)));
             } else {
                 throw Py::TypeError("the given shape must be a wire");
             }
         } else {
             throw Py::TypeError("the given shape is empty");
         }
     }
     catch (const Base::Exception& e) {
         throw Py::RuntimeError(e.what());
     }
     return Py::None();
 }
void ViewProviderRobotObject::updateData(const App::Property* prop)
{
    Robot::RobotObject* robObj = static_cast<Robot::RobotObject*>(pcObject);
    if (prop == &robObj->RobotVrmlFile) {
        // read also from file
        const char* filename = robObj->RobotVrmlFile.getValue();
        QString fn = QString::fromUtf8(filename);
        QFile file(fn);
        SoInput in;
        pcRobotRoot->removeAllChildren();
        if (!fn.isEmpty() && file.open(QFile::ReadOnly)) {
            QByteArray buffer = file.readAll();
            in.setBuffer((void *)buffer.constData(), buffer.length());
            SoSeparator * node = SoDB::readAll(&in);
            if (node) pcRobotRoot->addChild(node);
            pcRobotRoot->addChild(pcTcpRoot);
        }
		// search for the conection points +++++++++++++++++++++++++++++++++++++++++++++++++
		Axis1Node = Axis2Node = Axis3Node = Axis4Node = Axis5Node = Axis6Node = 0;
		SoSearchAction searchAction;
		SoPath * path;

		// Axis 1
		searchAction.setName("FREECAD_AXIS1");
		searchAction.setInterest(SoSearchAction::FIRST);
		searchAction.setSearchingAll(FALSE);
		searchAction.apply(pcRobotRoot);
		path = searchAction.getPath();
		if(path){
			SoNode* node = path->getTail();
			std::string typeName = (const char*)node->getTypeId().getName();
			if (!node || node->getTypeId() != SoVRMLTransform::getClassTypeId())
				throw; // should not happen
			Axis1Node = static_cast<SoVRMLTransform *>(node);
		}
		// Axis 2
		searchAction.setName("FREECAD_AXIS2");
		searchAction.setInterest(SoSearchAction::FIRST);
		searchAction.setSearchingAll(FALSE);
		searchAction.apply(pcRobotRoot);
		path = searchAction.getPath();
		if(path){
			SoNode* node = path->getTail();
			std::string typeName = (const char*)node->getTypeId().getName();
			if (!node || node->getTypeId() != SoVRMLTransform::getClassTypeId())
				throw; // should not happen
			Axis2Node = static_cast<SoVRMLTransform *>(node);
		}
		// Axis 3
		searchAction.setName("FREECAD_AXIS3");
		searchAction.setInterest(SoSearchAction::FIRST);
		searchAction.setSearchingAll(FALSE);
		searchAction.apply(pcRobotRoot);
		path = searchAction.getPath();
		if(path){
			SoNode* node = path->getTail();
			std::string typeName = (const char*)node->getTypeId().getName();
			if (!node || node->getTypeId() != SoVRMLTransform::getClassTypeId())
				throw; // should not happen
			Axis3Node = static_cast<SoVRMLTransform *>(node);
		}
		// Axis 4
		searchAction.setName("FREECAD_AXIS4");
		searchAction.setInterest(SoSearchAction::FIRST);
		searchAction.setSearchingAll(FALSE);
		searchAction.apply(pcRobotRoot);
		path = searchAction.getPath();
		if(path){
			SoNode* node = path->getTail();
			std::string typeName = (const char*)node->getTypeId().getName();
			if (!node || node->getTypeId() != SoVRMLTransform::getClassTypeId())
				throw; // should not happen
			Axis4Node = static_cast<SoVRMLTransform *>(node);
		}
		// Axis 5
		searchAction.setName("FREECAD_AXIS5");
		searchAction.setInterest(SoSearchAction::FIRST);
		searchAction.setSearchingAll(FALSE);
		searchAction.apply(pcRobotRoot);
		path = searchAction.getPath();
		if(path){
			SoNode* node = path->getTail();
			std::string typeName = (const char*)node->getTypeId().getName();
			if (!node || node->getTypeId() != SoVRMLTransform::getClassTypeId())
				throw; // should not happen
			Axis5Node = static_cast<SoVRMLTransform *>(node);
		}
		// Axis 6
		searchAction.setName("FREECAD_AXIS6");
		searchAction.setInterest(SoSearchAction::FIRST);
		searchAction.setSearchingAll(FALSE);
		searchAction.apply(pcRobotRoot);
		path = searchAction.getPath();
		if(path){
			SoNode* node = path->getTail();
			std::string typeName = (const char*)node->getTypeId().getName();
			if (!node || node->getTypeId() != SoVRMLTransform::getClassTypeId())
				throw; // should not happen
			Axis6Node = static_cast<SoVRMLTransform *>(node);
		}
		if(Axis1Node)
			Axis1Node->rotation.setValue(SbVec3f(0.0,1.0,0.0),robObj->Axis1.getValue()*(M_PI/180));
		if(Axis2Node)
			Axis2Node->rotation.setValue(SbVec3f(0.0,1.0,0.0),robObj->Axis2.getValue()*(M_PI/180));
		if(Axis3Node)
			Axis3Node->rotation.setValue(SbVec3f(0.0,1.0,0.0),robObj->Axis3.getValue()*(M_PI/180));
		if(Axis4Node)
			Axis4Node->rotation.setValue(SbVec3f(0.0,1.0,0.0),robObj->Axis4.getValue()*(M_PI/180));
		if(Axis5Node)
			Axis5Node->rotation.setValue(SbVec3f(0.0,1.0,0.0),robObj->Axis5.getValue()*(M_PI/180));
		if(Axis6Node)
			Axis6Node->rotation.setValue(SbVec3f(0.0,1.0,0.0),robObj->Axis6.getValue()*(M_PI/180));
    }else if (prop == &robObj->Axis1) {
        if(Axis1Node){
			Axis1Node->rotation.setValue(SbVec3f(0.0,1.0,0.0),robObj->Axis1.getValue()*(M_PI/180));
            if(toolShape)
                toolShape->setTransformation((robObj->Tcp.getValue() * (robObj->ToolBase.getValue().inverse())).toMatrix());
        }
    }else if (prop == &robObj->Axis2) {
        if(Axis2Node){
			Axis2Node->rotation.setValue(SbVec3f(0.0,1.0,0.0),robObj->Axis2.getValue()*(M_PI/180));
            if(toolShape)
                toolShape->setTransformation((robObj->Tcp.getValue() * (robObj->ToolBase.getValue().inverse())).toMatrix());
        }
    }else if (prop == &robObj->Axis3) {
        if(Axis3Node){
			Axis3Node->rotation.setValue(SbVec3f(0.0,1.0,0.0),robObj->Axis3.getValue()*(M_PI/180));
            if(toolShape)
                toolShape->setTransformation((robObj->Tcp.getValue() * (robObj->ToolBase.getValue().inverse())).toMatrix());
        }
    }else if (prop == &robObj->Axis4) {
        if(Axis4Node){
			Axis4Node->rotation.setValue(SbVec3f(0.0,1.0,0.0),robObj->Axis4.getValue()*(M_PI/180));
            if(toolShape)
                toolShape->setTransformation((robObj->Tcp.getValue() * (robObj->ToolBase.getValue().inverse())).toMatrix());
        }
    }else if (prop == &robObj->Axis5) {
        if(Axis5Node){
			Axis5Node->rotation.setValue(SbVec3f(0.0,1.0,0.0),robObj->Axis5.getValue()*(M_PI/180));
            if(toolShape)
                toolShape->setTransformation((robObj->Tcp.getValue() * (robObj->ToolBase.getValue().inverse())).toMatrix());
        }
    }else if (prop == &robObj->Axis6) {
        if(Axis6Node){
			Axis6Node->rotation.setValue(SbVec3f(0.0,1.0,0.0),robObj->Axis6.getValue()*(M_PI/180));
            if(toolShape)
                toolShape->setTransformation((robObj->Tcp.getValue() * (robObj->ToolBase.getValue().inverse())).toMatrix());
        }
	}else if (prop == &robObj->Tcp) {
        Base::Placement loc = robObj->Tcp.getValue();
        SbMatrix  M;
        M.setTransform(SbVec3f(loc.getPosition().x,loc.getPosition().y,loc.getPosition().z),
                       SbRotation(loc.getRotation()[0],loc.getRotation()[1],loc.getRotation()[2],loc.getRotation()[3]),
                       SbVec3f(150,150,150)
                       );
        if(pcDragger)
            pcDragger->setMotionMatrix(M);
        if(toolShape)
            toolShape->setTransformation((robObj->Tcp.getValue() * (robObj->ToolBase.getValue().inverse())).toMatrix());
		//pcTcpTransform->translation = SbVec3f(loc.getPosition().x,loc.getPosition().y,loc.getPosition().z);
		//pcTcpTransform->rotation = SbRotation(loc.getRotation()[0],loc.getRotation()[1],loc.getRotation()[2],loc.getRotation()[3]);
	}else if (prop == &robObj->ToolShape) {
        App::DocumentObject* o = robObj->ToolShape.getValue<App::DocumentObject*>();

        if(o && (o->isDerivedFrom(Part::Feature::getClassTypeId()) || o->isDerivedFrom(App::VRMLObject::getClassTypeId())) ){
            //Part::Feature *p = dynamic_cast<Part::Feature *>(o);
            toolShape = Gui::Application::Instance->getViewProvider(o);
            toolShape->setTransformation((robObj->Tcp.getValue() * (robObj->ToolBase.getValue().inverse())).toMatrix());
        }else
            toolShape = 0;
 	}

}
Exemple #24
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");
}
void ComplexGeoData::setPlacement(const Base::Placement& rclPlacement)
{
    setTransform(rclPlacement.toMatrix());
}
Exemple #26
0
/**
 * This method was added for backward-compatibility. In former versions
 * of Box we had the properties x,y,z and l,h,w which have changed to
 * Location -- as replacement for x,y and z and Length, Height and Width.
 */
void Box::Restore(Base::XMLReader &reader)
{
    reader.readElement("Properties");
    int Cnt = reader.getAttributeAsInteger("Count");

    bool location_xyz = false;
    bool location_axis = false;
    bool distance_lhw = false;
    Base::Placement plm;
    App::PropertyDistance x,y,z;
    App::PropertyDistance l,w,h;
    App::PropertyVector Axis, Location;
    Axis.setValue(0.0f,0.0f,1.0f);
    for (int i=0 ;i<Cnt;i++) {
        reader.readElement("Property");
        const char* PropName = reader.getAttribute("name");
        const char* TypeName = reader.getAttribute("type");
        App::Property* prop = getPropertyByName(PropName);
        if (!prop) {
            // in case this comes from an old document we must use the new properties
            if (strcmp(PropName, "l") == 0) {
                distance_lhw = true;
                prop = &l;
            }
            else if (strcmp(PropName, "w") == 0) {
                distance_lhw = true;
                prop = &h; // by mistake w was considered as height
            }
            else if (strcmp(PropName, "h") == 0) {
                distance_lhw = true;
                prop = &w; // by mistake h was considered as width
            }
            else if (strcmp(PropName, "x") == 0) {
                location_xyz = true;
                prop = &x;
            }
            else if (strcmp(PropName, "y") == 0) {
                location_xyz = true;
                prop = &y;
            }
            else if (strcmp(PropName, "z") == 0) {
                location_xyz = true;
                prop = &z;
            }
            else if (strcmp(PropName, "Axis") == 0) {
                location_axis = true;
                prop = &Axis;
            }
            else if (strcmp(PropName, "Location") == 0) {
                location_axis = true;
                prop = &Location;
            }
        }
        else if (strcmp(PropName, "Length") == 0 && strcmp(TypeName,"PropertyDistance") == 0) {
            distance_lhw = true;
            prop = &l;
        }
        else if (strcmp(PropName, "Height") == 0 && strcmp(TypeName,"PropertyDistance") == 0) {
            distance_lhw = true;
            prop = &h;
        }
        else if (strcmp(PropName, "Width") == 0 && strcmp(TypeName,"PropertyDistance") == 0) {
            distance_lhw = true;
            prop = &w;
        }

        // NOTE: We must also check the type of the current property because a subclass
        // of PropertyContainer might change the type of a property but not its name.
        // In this case we would force to read-in a wrong property type and the behaviour
        // would be undefined.
        std::string tn = TypeName;
        if (strcmp(TypeName,"PropertyDistance") == 0) // missing prefix App::
            tn = std::string("App::") + tn;
        if (prop && strcmp(prop->getTypeId().getName(), tn.c_str()) == 0)
            prop->Restore(reader);

        reader.readEndElement("Property");
    }

    if (distance_lhw) {
        this->Length.setValue(l.getValue());
        this->Height.setValue(h.getValue());
        this->Width.setValue(w.getValue());
    }

    // for 0.7 releases or earlier
    if (location_xyz) {
        plm.setPosition(Base::Vector3d(x.getValue(),y.getValue(),z.getValue()));
        this->Placement.setValue(this->Placement.getValue() * plm);
        this->Shape.setStatus(App::Property::User1, true); // override the shape's location later on
    }
    // for 0.8 releases
    else if (location_axis) {
        Base::Vector3d d = Axis.getValue();
        Base::Vector3d p = Location.getValue();
        Base::Rotation rot(Base::Vector3d(0.0,0.0,1.0),
                           Base::Vector3d(d.x,d.y,d.z));
        plm.setRotation(rot);
        plm.setPosition(Base::Vector3d(p.x,p.y,p.z));
        this->Placement.setValue(this->Placement.getValue() * plm);
        this->Shape.setStatus(App::Property::User1, true); // override the shape's location later on
    }

    reader.readEndElement("Properties");
}
App::DocumentObjectExecReturn *Pocket::execute(void)
{
    // Handle legacy features, these typically have Type set to 3 (previously NULL, now UpToFace),
    // empty FaceName (because it didn't exist) and a value for Length
    if (std::string(Type.getValueAsString()) == "UpToFace" &&
        (UpToFace.getValue() == NULL && Length.getValue() > Precision::Confusion()))
        Type.setValue("Length");

    // Validate parameters
    double L = Length.getValue();
    if ((std::string(Type.getValueAsString()) == "Length") && (L < Precision::Confusion()))
        return new App::DocumentObjectExecReturn("Pocket: Length of pocket too small");

    Part::Part2DObject* sketch = 0;
    std::vector<TopoDS_Wire> wires;
    TopoDS_Shape support;
    try {
        sketch = getVerifiedSketch();
        wires = getSketchWires();
        support = getSupportShape();
    } catch (const Base::Exception& e) {
        return new App::DocumentObjectExecReturn(e.what());
    }

    // get the Sketch plane
    Base::Placement SketchPos = sketch->Placement.getValue();
    Base::Rotation SketchOrientation = SketchPos.getRotation();
    Base::Vector3d SketchVector(0,0,1);
    SketchOrientation.multVec(SketchVector,SketchVector);

    // turn around for pockets
    SketchVector *= -1;

    this->positionBySketch();
    TopLoc_Location invObjLoc = this->getLocation().Inverted();

    try {
        support.Move(invObjLoc);

        gp_Dir dir(SketchVector.x,SketchVector.y,SketchVector.z);
        dir.Transform(invObjLoc.Transformation());

        TopoDS_Shape sketchshape = makeFace(wires);
        if (sketchshape.IsNull())
            return new App::DocumentObjectExecReturn("Pocket: Creating a face from sketch failed");
        sketchshape.Move(invObjLoc);

        std::string method(Type.getValueAsString());
        if (method == "UpToFirst" || method == "UpToFace") {
            TopoDS_Face supportface = getSupportFace();
            supportface.Move(invObjLoc);

            // Find a valid face to extrude up to
            TopoDS_Face upToFace;
            if (method == "UpToFace") {
                getUpToFaceFromLinkSub(upToFace, UpToFace);
                upToFace.Move(invObjLoc);
            }
            getUpToFace(upToFace, support, supportface, sketchshape, method, dir);

            // Special treatment because often the created stand-alone prism is invalid (empty) because
            // BRepFeat_MakePrism(..., 2, 1) is buggy
            BRepFeat_MakePrism PrismMaker;
            PrismMaker.Init(support, sketchshape, supportface, dir, 0, 1);
            PrismMaker.Perform(upToFace);

            if (!PrismMaker.IsDone())
                return new App::DocumentObjectExecReturn("Pocket: Up to face: Could not extrude the sketch!");
            TopoDS_Shape prism = PrismMaker.Shape();
            prism = refineShapeIfActive(prism);

            // And the really expensive way to get the SubShape...
            BRepAlgoAPI_Cut mkCut(support, prism);
            if (!mkCut.IsDone())
                return new App::DocumentObjectExecReturn("Pocket: Up to face: Could not get SubShape!");
            // FIXME: In some cases this affects the Shape property: It is set to the same shape as the SubShape!!!!
            TopoDS_Shape result = refineShapeIfActive(mkCut.Shape());
            this->SubShape.setValue(result);
            this->Shape.setValue(prism);
        } else {
            TopoDS_Shape prism;
            generatePrism(prism, sketchshape, method, dir, L, 0.0,
                          Midplane.getValue(), Reversed.getValue());
            if (prism.IsNull())
                return new App::DocumentObjectExecReturn("Pocket: Resulting shape is empty");

            // set the subtractive shape property for later usage in e.g. pattern
            prism = refineShapeIfActive(prism);
            this->SubShape.setValue(prism);

            // Cut the SubShape out of the support
            BRepAlgoAPI_Cut mkCut(support, prism);
            if (!mkCut.IsDone())
                return new App::DocumentObjectExecReturn("Pocket: Cut out of support failed");
            TopoDS_Shape result = mkCut.Shape();
            // we have to get the solids (fuse sometimes creates compounds)
            TopoDS_Shape solRes = this->getSolid(result);
            if (solRes.IsNull())
                return new App::DocumentObjectExecReturn("Pocket: Resulting shape is not a solid");
            solRes = refineShapeIfActive(solRes);
            remapSupportShape(solRes);
            this->Shape.setValue(solRes);
        }

        return App::DocumentObject::StdReturn;
    }
    catch (Standard_Failure) {
        Handle_Standard_Failure e = Standard_Failure::Caught();
        if (std::string(e->GetMessageString()) == "TopoDS::Face" &&
            (std::string(Type.getValueAsString()) == "UpToFirst" || std::string(Type.getValueAsString()) == "UpToFace"))
            return new App::DocumentObjectExecReturn("Could not create face from sketch.\n"
                "Intersecting sketch entities or multiple faces in a sketch are not allowed "
                "for making a pocket up to a face.");
        else
            return new App::DocumentObjectExecReturn(e->GetMessageString());
    }
    catch (Base::Exception& e) {
        return new App::DocumentObjectExecReturn(e.what());
    }
}
Exemple #28
0
void Placement::applyPlacement(const Base::Placement& p, bool incremental, bool data)
{
    Gui::Document* document = Application::Instance->activeDocument();
    if (!document) return;

    std::vector<App::DocumentObject*> sel = Gui::Selection().getObjectsOfType
        (App::DocumentObject::getClassTypeId(), document->getDocument()->getName());
    if (!sel.empty()) {
        if (data) {
            document->openCommand("Placement");
            for (std::vector<App::DocumentObject*>::iterator it=sel.begin();it!=sel.end();++it) {
                std::map<std::string,App::Property*> props;
                (*it)->getPropertyMap(props);
                // search for the placement property
                std::map<std::string,App::Property*>::iterator jt;
                jt = std::find_if(props.begin(), props.end(), find_placement(this->propertyName));
                if (jt != props.end()) {
                    Base::Placement cur = static_cast<App::PropertyPlacement*>(jt->second)->getValue();
                    if (incremental)
                        cur = p * cur;
                    else
                        cur = p;

                    Base::Vector3d pos = cur.getPosition();
                    const Base::Rotation& rt = cur.getRotation();
                    QString cmd = QString::fromAscii(
                        "App.getDocument(\"%1\").%2.Placement="
                        "App.Placement("
                        "App.Vector(%3,%4,%5),"
                        "App.Rotation(%6,%7,%8,%9))\n")
                        .arg(QLatin1String((*it)->getDocument()->getName()))
                        .arg(QLatin1String((*it)->getNameInDocument()))
                        .arg(pos.x,0,'g',6)
                        .arg(pos.y,0,'g',6)
                        .arg(pos.z,0,'g',6)
                        .arg(rt[0],0,'g',6)
                        .arg(rt[1],0,'g',6)
                        .arg(rt[2],0,'g',6)
                        .arg(rt[3],0,'g',6);
                    Application::Instance->runPythonCode((const char*)cmd.toAscii());
                }
            }

            document->commitCommand();
            try {
                document->getDocument()->recompute();
            }
            catch (...) {
            }
        }
        // apply transformation only on view matrix not on placement property
        else {
            for (std::vector<App::DocumentObject*>::iterator it=sel.begin();it!=sel.end();++it) {
                std::map<std::string,App::Property*> props;
                (*it)->getPropertyMap(props);
                // search for the placement property
                std::map<std::string,App::Property*>::iterator jt;
                jt = std::find_if(props.begin(), props.end(), find_placement(this->propertyName));
                if (jt != props.end()) {
                    Base::Placement cur = static_cast<App::PropertyPlacement*>(jt->second)->getValue();
                    if (incremental)
                        cur = p * cur;
                    else
                        cur = p;

                    Gui::ViewProvider* vp = document->getViewProvider(*it);
                    if (vp) vp->setTransformation(cur.toMatrix());
                }
            }
        }
    }
    else {
        Base::Console().Warning("No object selected.\n");
    }
}
App::DocumentObjectExecReturn *Pad::execute(void)
{
    // Validate parameters
    double L = Length.getValue();
    if ((std::string(Type.getValueAsString()) == "Length") && (L < Precision::Confusion()))
        return new App::DocumentObjectExecReturn("Length of pad too small");
    double L2 = Length2.getValue();
    if ((std::string(Type.getValueAsString()) == "TwoLengths") && (L < Precision::Confusion()))
        return new App::DocumentObjectExecReturn("Second length of pad too small");

    Part::Part2DObject* sketch = 0;
    std::vector<TopoDS_Wire> wires;
    try {
        sketch = getVerifiedSketch();
        wires = getSketchWires();
    } catch (const Base::Exception& e) {
        return new App::DocumentObjectExecReturn(e.what());
    }

    TopoDS_Shape support;
    try {
        support = getSupportShape();
    } catch (const Base::Exception&) {
        // ignore, because support isn't mandatory
        support = TopoDS_Shape();
    }

    // get the Sketch plane
    Base::Placement SketchPos = sketch->Placement.getValue();
    Base::Rotation SketchOrientation = SketchPos.getRotation();
    Base::Vector3d SketchVector(0,0,1);
    SketchOrientation.multVec(SketchVector,SketchVector);

    this->positionBySketch();
    TopLoc_Location invObjLoc = this->getLocation().Inverted();

    try {
        support.Move(invObjLoc);

        gp_Dir dir(SketchVector.x,SketchVector.y,SketchVector.z);
        dir.Transform(invObjLoc.Transformation());

        TopoDS_Shape sketchshape = makeFace(wires);
        if (sketchshape.IsNull())
            return new App::DocumentObjectExecReturn("Pad: Creating a face from sketch failed");
        sketchshape.Move(invObjLoc);

        TopoDS_Shape prism;
        std::string method(Type.getValueAsString());
        if (method == "UpToFirst" || method == "UpToLast" || method == "UpToFace") {
            TopoDS_Face supportface = getSupportFace();
            supportface.Move(invObjLoc);

            if (Reversed.getValue())
                dir.Reverse();

            // Find a valid face to extrude up to
            TopoDS_Face upToFace;
            if (method == "UpToFace") {
                getUpToFaceFromLinkSub(upToFace, UpToFace);
                upToFace.Move(invObjLoc);
            }
            getUpToFace(upToFace, support, supportface, sketchshape, method, dir);

            // A support object is always required and we need to use BRepFeat_MakePrism
            // Problem: For Pocket/UpToFirst (or an equivalent Pocket/UpToFace) the resulting shape is invalid
            // because the feature does not add any material. This only happens with the "2" option, though
            // Note: It might be possible to pass a shell or a compound containing multiple faces
            // as the Until parameter of Perform()
            BRepFeat_MakePrism PrismMaker;
            PrismMaker.Init(support, sketchshape, supportface, dir, 2, 1);
            PrismMaker.Perform(upToFace);

            if (!PrismMaker.IsDone())
                return new App::DocumentObjectExecReturn("Pad: Up to face: Could not extrude the sketch!");
            prism = PrismMaker.Shape();
        } else {
            generatePrism(prism, sketchshape, method, dir, L, L2,
                          Midplane.getValue(), Reversed.getValue());
        }

        if (prism.IsNull())
            return new App::DocumentObjectExecReturn("Pad: Resulting shape is empty");

        // set the additive shape property for later usage in e.g. pattern
        this->AddShape.setValue(prism);

        // if the sketch has a support fuse them to get one result object
        if (!support.IsNull()) {
            // Let's call algorithm computing a fuse operation:
            BRepAlgoAPI_Fuse mkFuse(support, prism);
            // Let's check if the fusion has been successful
            if (!mkFuse.IsDone())
                return new App::DocumentObjectExecReturn("Pad: Fusion with support failed");
            TopoDS_Shape result = mkFuse.Shape();
            // we have to get the solids (fuse sometimes creates compounds)
            TopoDS_Shape solRes = this->getSolid(result);
            // lets check if the result is a solid
            if (solRes.IsNull())
                return new App::DocumentObjectExecReturn("Pad: Resulting shape is not a solid");
            this->Shape.setValue(solRes);
        } else {
            this->Shape.setValue(prism);
        }

        return App::DocumentObject::StdReturn;
    }
    catch (Standard_Failure) {
        Handle_Standard_Failure e = Standard_Failure::Caught();
        if (std::string(e->GetMessageString()) == "TopoDS::Face")
            return new App::DocumentObjectExecReturn("Could not create face from sketch.\n"
                "Intersecting sketch entities or multiple faces in a sketch are not allowed.");
        else
            return new App::DocumentObjectExecReturn(e->GetMessageString());
    }
    catch (Base::Exception& e) {
        return new App::DocumentObjectExecReturn(e.what());
    }
}
Exemple #30
0
void Part2DObject::positionBySupport(void)
{
    // recalculate support:
    Part::Feature *part = static_cast<Part::Feature*>(Support.getValue());
    if (!part || !part->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId()))
        return;

    Base::Placement Place = part->Placement.getValue();
    const std::vector<std::string> &sub = Support.getSubValues();
    assert(sub.size()==1);
    // get the selected sub shape (a Face)
    const Part::TopoShape &shape = part->Shape.getShape();
    if (shape._Shape.IsNull())
        throw Base::Exception("Support shape is empty!");
    TopoDS_Shape sh;
    try {
        sh = shape.getSubShape(sub[0].c_str());
    }
    catch (Standard_Failure) {
        throw Base::Exception("Face in support shape doesn't exist!");
    }
    const TopoDS_Face &face = TopoDS::Face(sh);
    if (face.IsNull())
        throw Base::Exception("Null face in Part2DObject::positionBySupport()!");

    BRepAdaptor_Surface adapt(face);
    if (adapt.GetType() != GeomAbs_Plane)
        throw Base::Exception("No planar face in Part2DObject::positionBySupport()!");

    bool Reverse = false;
    if (face.Orientation() == TopAbs_REVERSED)
        Reverse = true;

    gp_Pln plane = adapt.Plane();
    Standard_Boolean ok = plane.Direct();
    if (!ok) {
        // toggle if plane has a left-handed coordinate system
        plane.UReverse();
        Reverse = !Reverse;
    }

    gp_Ax1 Normal = plane.Axis();
    if (Reverse)
        Normal.Reverse();

    gp_Pnt ObjOrg(Place.getPosition().x,Place.getPosition().y,Place.getPosition().z);

    Handle (Geom_Plane) gPlane = new Geom_Plane(plane);
    GeomAPI_ProjectPointOnSurf projector(ObjOrg,gPlane);
    gp_Pnt SketchBasePoint = projector.NearestPoint();

    gp_Dir dir = Normal.Direction();
    gp_Ax3 SketchPos;

    Base::Vector3d dX,dY,dZ;
    Place.getRotation().multVec(Base::Vector3d(1,0,0),dX);
    Place.getRotation().multVec(Base::Vector3d(0,1,0),dY);
    Place.getRotation().multVec(Base::Vector3d(0,0,1),dZ);
    gp_Dir dirX(dX.x, dX.y, dX.z);
    gp_Dir dirY(dY.x, dY.y, dY.z);
    gp_Dir dirZ(dZ.x, dZ.y, dZ.z);
    double cosNX = dir.Dot(dirX);
    double cosNY = dir.Dot(dirY);
    double cosNZ = dir.Dot(dirZ);
    std::vector<double> cosXYZ;
    cosXYZ.push_back(fabs(cosNX));
    cosXYZ.push_back(fabs(cosNY));
    cosXYZ.push_back(fabs(cosNZ));

    int pos = std::max_element(cosXYZ.begin(), cosXYZ.end()) - cosXYZ.begin();

    // +X/-X
    if (pos == 0) {
        if (cosNX > 0)
            SketchPos = gp_Ax3(SketchBasePoint, dir, dirY);
        else
            SketchPos = gp_Ax3(SketchBasePoint, dir, -dirY);
    }
    // +Y/-Y
    else if (pos == 1) {
        if (cosNY > 0)
            SketchPos = gp_Ax3(SketchBasePoint, dir, -dirX);
        else
            SketchPos = gp_Ax3(SketchBasePoint, dir, dirX);
    }
    // +Z/-Z
    else {
        SketchPos = gp_Ax3(SketchBasePoint, dir, dirX);
    }

    gp_Trsf Trf;
    Trf.SetTransformation(SketchPos);
    Trf.Invert();

    Base::Matrix4D mtrx;

    gp_Mat m = Trf._CSFDB_Getgp_Trsfmatrix();
    gp_XYZ p = Trf._CSFDB_Getgp_Trsfloc();
    Standard_Real scale = 1.0;

    // set Rotation matrix
    mtrx[0][0] = scale * m._CSFDB_Getgp_Matmatrix(0,0);
    mtrx[0][1] = scale * m._CSFDB_Getgp_Matmatrix(0,1);
    mtrx[0][2] = scale * m._CSFDB_Getgp_Matmatrix(0,2);

    mtrx[1][0] = scale * m._CSFDB_Getgp_Matmatrix(1,0);
    mtrx[1][1] = scale * m._CSFDB_Getgp_Matmatrix(1,1);
    mtrx[1][2] = scale * m._CSFDB_Getgp_Matmatrix(1,2);

    mtrx[2][0] = scale * m._CSFDB_Getgp_Matmatrix(2,0);
    mtrx[2][1] = scale * m._CSFDB_Getgp_Matmatrix(2,1);
    mtrx[2][2] = scale * m._CSFDB_Getgp_Matmatrix(2,2);

    // set pos vector
    mtrx[0][3] = p._CSFDB_Getgp_XYZx();
    mtrx[1][3] = p._CSFDB_Getgp_XYZy();
    mtrx[2][3] = p._CSFDB_Getgp_XYZz();

    // check the angle against the Z Axis
    //Standard_Real a = Normal.Angle(gp_Ax1(gp_Pnt(0,0,0),gp_Dir(0,0,1)));

    Placement.setValue(Base::Placement(mtrx));
}