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); }
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)); }
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()); } }
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()); } }
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(); }
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); } }
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; } }
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()); }
/** * 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()); } }
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()); } }
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)); }