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); }
Base::Vector3d ProfileBased::getProfileNormal() const { Base::Vector3d SketchVector(0,0,1); auto obj = getVerifiedObject(true); if(!obj) return SketchVector; // get the Sketch plane if(obj->isDerivedFrom(Part::Part2DObject::getClassTypeId())) { Base::Placement SketchPos = obj->Placement.getValue(); Base::Rotation SketchOrientation = SketchPos.getRotation(); SketchOrientation.multVec(SketchVector,SketchVector); } else { TopoDS_Shape shape = getVerifiedFace(true); if (shape == TopoDS_Shape()) return SketchVector; if (shape.ShapeType() == TopAbs_FACE) { BRepAdaptor_Surface adapt(TopoDS::Face(shape)); double u = adapt.FirstUParameter() + (adapt.LastUParameter() - adapt.FirstUParameter())/2.; double v = adapt.FirstVParameter() + (adapt.LastVParameter() - adapt.FirstVParameter())/2.; BRepLProp_SLProps prop(adapt,u,v,2,Precision::Confusion()); if(prop.IsNormalDefined()) { gp_Pnt pnt; gp_Vec vec; // handles the orientation state of the shape BRepGProp_Face(TopoDS::Face(shape)).Normal(u,v,pnt,vec); SketchVector = Base::Vector3d(vec.X(), vec.Y(), vec.Z()); } } } return SketchVector; }
double ProfileBased::getReversedAngle(const Base::Vector3d &b, const Base::Vector3d &v) { try { Part::Feature* obj = getVerifiedObject(); TopoDS_Shape sketchshape = getVerifiedFace(); // 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 = obj->Placement.getValue(); Base::Rotation SketchOrientation = SketchPos.getRotation(); Base::Vector3d SketchNormal(0,0,1); SketchOrientation.multVec(SketchNormal,SketchNormal); return SketchNormal * cross; } catch (...) { return Reversed.getValue() ? 1 : 0; } }
Command Command::transform(const Base::Placement other) { Base::Placement plac = getPlacement(); plac *= other; double xval, yval, zval, aval, bval, cval; xval = plac.getPosition().x; yval = plac.getPosition().y; zval = plac.getPosition().z; plac.getRotation().getYawPitchRoll(aval,bval,cval); Command c = Command(); c.Name = Name; for(std::map<std::string,double>::const_iterator i = Parameters.begin(); i != Parameters.end(); ++i) { std::string k = i->first; double v = i->second; if (k == "X") v = xval; if (k == "Y") v = yval; if (k == "Z") v = zval; if (k == "A") v = aval; if (k == "B") v = bval; if (k == "C") v = cval; c.Parameters[k] = v; } return c; }
void Command::setFromPlacement (const Base::Placement &plac) { Name = "G1"; Parameters.clear(); std::string x = "X"; std::string y = "Y"; std::string z = "Z"; std::string a = "A"; std::string b = "B"; std::string c = "C"; double xval, yval, zval, aval, bval, cval; xval = plac.getPosition().x; yval = plac.getPosition().y; zval = plac.getPosition().z; plac.getRotation().getYawPitchRoll(aval,bval,cval); if (xval != 0.0) Parameters[x] = xval; if (yval != 0.0) Parameters[y] = yval; if (zval != 0.0) Parameters[z] = zval; if (aval != 0.0) Parameters[a] = aval; if (bval != 0.0) Parameters[b] = bval; if (cval != 0.0) Parameters[c] = cval; }
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::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); }
TopLoc_Location FeatureReference::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 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 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); }
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 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(); }
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::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 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)); }
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 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 *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 CmdApproxPlane::activated(int iMsg) { std::vector<App::GeoFeature*> obj = Gui::Selection().getObjectsOfType<App::GeoFeature>(); for (std::vector<App::GeoFeature*>::iterator it = obj.begin(); it != obj.end(); ++it) { std::map<std::string, App::Property*> Map; (*it)->getPropertyMap(Map); for (std::map<std::string, App::Property*>::iterator jt = Map.begin(); jt != Map.end(); ++jt) { if (jt->second->getTypeId().isDerivedFrom(App::PropertyComplexGeoData::getClassTypeId())) { std::vector<Base::Vector3d> aPoints; std::vector<Data::ComplexGeoData::Facet> aTopo; static_cast<App::PropertyComplexGeoData*>(jt->second)->getFaces(aPoints, aTopo,0.01f); // get a reference normal for the plane fit Base::Vector3f refNormal(0,0,0); if (!aTopo.empty()) { Data::ComplexGeoData::Facet f = aTopo.front(); Base::Vector3d v1 = aPoints[f.I2] - aPoints[f.I1]; Base::Vector3d v2 = aPoints[f.I3] - aPoints[f.I1]; refNormal = Base::convertTo<Base::Vector3f>(v1 % v2); } std::vector<Base::Vector3f> aData; aData.reserve(aPoints.size()); for (std::vector<Base::Vector3d>::iterator jt = aPoints.begin(); jt != aPoints.end(); ++jt) aData.push_back(Base::toVector<float>(*jt)); MeshCore::PlaneFit fit; fit.AddPoints(aData); float sigma = fit.Fit(); Base::Vector3f base = fit.GetBase(); Base::Vector3f dirU = fit.GetDirU(); Base::Vector3f dirV = fit.GetDirV(); Base::Vector3f norm = fit.GetNormal(); // if the dot product of the reference with the plane normal is negative // a flip must be done if (refNormal * norm < 0) { norm = -norm; dirU = -dirU; } float width, length; fit.Dimension(width, length); // move to the corner point base = base - (0.5f * length * dirU + 0.5f * width * dirV); Base::CoordinateSystem cs; cs.setPosition(Base::convertTo<Base::Vector3d>(base)); cs.setAxes(Base::convertTo<Base::Vector3d>(norm), Base::convertTo<Base::Vector3d>(dirU)); Base::Placement pm = Base::CoordinateSystem().displacement(cs); double q0, q1, q2, q3; pm.getRotation().getValue(q0, q1, q2, q3); Base::Console().Log("RMS value for plane fit with %lu points: %.4f\n", aData.size(), sigma); Base::Console().Log(" Plane base(%.4f, %.4f, %.4f)\n", base.x, base.y, base.z); Base::Console().Log(" Plane normal(%.4f, %.4f, %.4f)\n", norm.x, norm.y, norm.z); std::stringstream str; str << "from FreeCAD import Base" << std::endl; str << "App.ActiveDocument.addObject('Part::Plane','Plane_fit')" << std::endl; str << "App.ActiveDocument.ActiveObject.Length = " << length << std::endl; str << "App.ActiveDocument.ActiveObject.Width = " << width << std::endl; str << "App.ActiveDocument.ActiveObject.Placement = Base.Placement(" << "Base.Vector(" << base.x << "," << base.y << "," << base.z << ")," << "Base.Rotation(" << q0 << "," << q1 << "," << q2 << "," << q3 << "))" << std::endl; openCommand("Fit plane"); doCommand(Gui::Command::Doc, str.str().c_str()); commitCommand(); updateActive(); } } } }
bool TaskDlgDatumParameters::accept() { std::string name = DatumView->getObject()->getNameInDocument(); Part::Datum* pcDatum = static_cast<Part::Datum*>(DatumView->getObject()); auto pcActiveBody = PartDesignGui::getBodyFor(pcDatum, false); auto pcActivePart = PartDesignGui::getPartFor(pcActiveBody, false); std::vector<App::DocumentObject*> copies; //see if we are able to assign a mode if (parameter->getActiveMapMode() == mmDeactivated) { QMessageBox msg; msg.setWindowTitle(tr("Incompatible reference set")); msg.setText(tr("There is no attachment mode that fits the current set" " of references. If you choose to continue, the feature will remain where" " it is now, and will not be moved as the references change." " Continue?")); msg.addButton(QMessageBox::Yes); auto btNo = msg.addButton(QMessageBox::No); msg.setDefaultButton(btNo); msg.setIcon(QMessageBox::Warning); msg.exec(); if (msg.clickedButton() == btNo) return false; } //see what to do with external references //check the prerequisites for the selected objects //the user has to decide which option we should take if external references are used bool ext = false; for(App::DocumentObject* obj : pcDatum->Support.getValues()) { if(!pcActiveBody->hasFeature(obj) && !pcActiveBody->getOrigin()->hasObject(obj)) ext = true; } if(ext) { // TODO rewrite this to be shared with CmdPartDesignNewSketch::activated() (2015-10-20, Fat-Zer) QDialog* dia = new QDialog; Ui_Dialog dlg; dlg.setupUi(dia); dia->setModal(true); int result = dia->exec(); if(result == QDialog::DialogCode::Rejected) return false; else if(!dlg.radioXRef->isChecked()) { std::vector<App::DocumentObject*> objs; std::vector<std::string> subs = pcDatum->Support.getSubValues(); int index = 0; for(App::DocumentObject* obj : pcDatum->Support.getValues()) { if(!pcActiveBody->hasFeature(obj) && !pcActiveBody->getOrigin()->hasObject(obj)) { objs.push_back(PartDesignGui::TaskFeaturePick::makeCopy(obj, subs[index], dlg.radioIndependent->isChecked())); copies.push_back(objs.back()); subs[index] = ""; } else objs.push_back(obj); index++; } pcDatum->Support.setValues(objs, subs); } } try { //DeepSOIC: changed this to heavily rely on dialog constantly updating feature properties if (pcDatum->superPlacement.isTouched()){ Base::Placement plm = pcDatum->superPlacement.getValue(); double yaw, pitch, roll; plm.getRotation().getYawPitchRoll(yaw,pitch,roll); Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.superPlacement = App.Placement(App.Vector(%.10f, %.10f, %.10f), App.Rotation(%.10f, %.10f, %.10f))", name.c_str(), plm.getPosition().x, plm.getPosition().y, plm.getPosition().z, yaw, pitch, roll); } Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.MapReversed = %s", name.c_str(), pcDatum->MapReversed.getValue() ? "True" : "False"); Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Support = %s", name.c_str(), pcDatum->Support.getPyReprString().c_str()); Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.MapMode = '%s'", name.c_str(), AttachEngine::getModeName(eMapMode(pcDatum->MapMode.getValue())).c_str()); Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.recompute()"); if (!DatumView->getObject()->isValid()) throw Base::Exception(DatumView->getObject()->getStatusString()); Gui::Command::doCommand(Gui::Command::Gui, "Gui.activeDocument().resetEdit()"); Gui::Command::commitCommand(); //we need to add the copied features to the body after the command action, as otherwise freecad crashs unexplainable for(auto obj : copies) { if(pcActiveBody) pcActiveBody->addFeature(obj); else if (pcActivePart) pcActivePart->addObject(obj); } } catch (const Base::Exception& e) { QMessageBox::warning(parameter, tr("Datum dialog: Input error"), QString::fromLatin1(e.what())); return false; } return true; }
void ViewProviderDragger::updatePlacementFromDragger(ViewProviderDragger* sudoThis, SoFCCSysDragger* draggerIn) { App::DocumentObject *genericObject = sudoThis->getObject(); if (!genericObject->isDerivedFrom(App::GeoFeature::getClassTypeId())) return; App::GeoFeature *geoFeature = static_cast<App::GeoFeature *>(genericObject); Base::Placement originalPlacement = geoFeature->Placement.getValue(); double pMatrix[16]; originalPlacement.toMatrix().getMatrix(pMatrix); Base::Placement freshPlacement = originalPlacement; //local cache for brevity. double translationIncrement = draggerIn->translationIncrement.getValue(); double rotationIncrement = draggerIn->rotationIncrement.getValue(); int tCountX = draggerIn->translationIncrementCountX.getValue(); int tCountY = draggerIn->translationIncrementCountY.getValue(); int tCountZ = draggerIn->translationIncrementCountZ.getValue(); int rCountX = draggerIn->rotationIncrementCountX.getValue(); int rCountY = draggerIn->rotationIncrementCountY.getValue(); int rCountZ = draggerIn->rotationIncrementCountZ.getValue(); //just as a little sanity check make sure only 1 field has changed. int numberOfFieldChanged = 0; if (tCountX) numberOfFieldChanged++; if (tCountY) numberOfFieldChanged++; if (tCountZ) numberOfFieldChanged++; if (rCountX) numberOfFieldChanged++; if (rCountY) numberOfFieldChanged++; if (rCountZ) numberOfFieldChanged++; if (numberOfFieldChanged == 0) return; assert(numberOfFieldChanged == 1); //helper lamdas. auto getVectorX = [&pMatrix]() {return Base::Vector3d(pMatrix[0], pMatrix[4], pMatrix[8]);}; auto getVectorY = [&pMatrix]() {return Base::Vector3d(pMatrix[1], pMatrix[5], pMatrix[9]);}; auto getVectorZ = [&pMatrix]() {return Base::Vector3d(pMatrix[2], pMatrix[6], pMatrix[10]);}; if (tCountX) { Base::Vector3d movementVector(getVectorX()); movementVector *= (tCountX * translationIncrement); freshPlacement.move(movementVector); geoFeature->Placement.setValue(freshPlacement); } else if (tCountY) { Base::Vector3d movementVector(getVectorY()); movementVector *= (tCountY * translationIncrement); freshPlacement.move(movementVector); geoFeature->Placement.setValue(freshPlacement); } else if (tCountZ) { Base::Vector3d movementVector(getVectorZ()); movementVector *= (tCountZ * translationIncrement); freshPlacement.move(movementVector); geoFeature->Placement.setValue(freshPlacement); } else if (rCountX) { Base::Vector3d rotationVector(getVectorX()); Base::Rotation rotation(rotationVector, rCountX * rotationIncrement); freshPlacement.setRotation(rotation * freshPlacement.getRotation()); geoFeature->Placement.setValue(freshPlacement); } else if (rCountY) { Base::Vector3d rotationVector(getVectorY()); Base::Rotation rotation(rotationVector, rCountY * rotationIncrement); freshPlacement.setRotation(rotation * freshPlacement.getRotation()); geoFeature->Placement.setValue(freshPlacement); } else if (rCountZ) { Base::Vector3d rotationVector(getVectorZ()); Base::Rotation rotation(rotationVector, rCountZ * rotationIncrement); freshPlacement.setRotation(rotation * freshPlacement.getRotation()); geoFeature->Placement.setValue(freshPlacement); } draggerIn->clearIncrementCounts(); }
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); } }
void CmdSketcherMirrorSketch::activated(int iMsg) { std::vector<Gui::SelectionObject> selection = getSelection().getSelectionEx(0, Sketcher::SketchObject::getClassTypeId()); if (selection.size() < 1) { QMessageBox::warning(Gui::getMainWindow(), qApp->translate("CmdSketcherMirrorSketch", "Wrong selection"), qApp->translate("CmdSketcherMirrorSketch", "Select one or more sketches, please.")); return; } // Ask the user which kind of mirroring he wants SketchMirrorDialog * smd = new SketchMirrorDialog(); int refgeoid=-1; Sketcher::PointPos refposid=Sketcher::none; if( smd->exec() == QDialog::Accepted ){ refgeoid=smd->RefGeoid; refposid=smd->RefPosid; delete smd; } else { delete smd; return; } App::Document* doc = App::GetApplication().getActiveDocument(); openCommand("Create a mirror Sketch for each sketch"); for (std::vector<Gui::SelectionObject>::const_iterator it=selection.begin(); it != selection.end(); ++it) { // create Sketch std::string FeatName = getUniqueObjectName("MirroredSketch"); doCommand(Doc,"App.activeDocument().addObject('Sketcher::SketchObject','%s')",FeatName.c_str()); Sketcher::SketchObject* mirrorsketch = static_cast<Sketcher::SketchObject*>(doc->getObject(FeatName.c_str())); const Sketcher::SketchObject* Obj = static_cast<const Sketcher::SketchObject*>((*it).getObject()); Base::Placement pl = Obj->Placement.getValue(); Base::Vector3d p = pl.getPosition(); Base::Rotation r = pl.getRotation(); doCommand(Doc,"App.activeDocument().%s.Placement = App.Placement(App.Vector(%f,%f,%f),App.Rotation(%f,%f,%f,%f))", FeatName.c_str(), p.x,p.y,p.z,r[0],r[1],r[2],r[3]); Sketcher::SketchObject* tempsketch = new Sketcher::SketchObject(); int addedGeometries=tempsketch->addGeometry(Obj->getInternalGeometry()); int addedConstraints=tempsketch->addConstraints(Obj->Constraints.getValues()); std::vector<int> geoIdList; for(int i=0;i<=addedGeometries;i++) geoIdList.push_back(i); tempsketch->addSymmetric(geoIdList, refgeoid, refposid); std::vector<Part::Geometry *> tempgeo = tempsketch->getInternalGeometry(); std::vector<Sketcher::Constraint *> tempconstr = tempsketch->Constraints.getValues(); std::vector<Part::Geometry *> mirrorgeo (tempgeo.begin()+addedGeometries+1,tempgeo.end()); std::vector<Sketcher::Constraint *> mirrorconstr (tempconstr.begin()+addedConstraints+1,tempconstr.end()); for(std::vector<Sketcher::Constraint *>::const_iterator itc=mirrorconstr.begin(); itc != mirrorconstr.end(); ++itc) { if((*itc)->First!=Sketcher::Constraint::GeoUndef || (*itc)->First==-1 || (*itc)->First==-2) // not x, y axes or origin (*itc)->First-=(addedGeometries+1); if((*itc)->Second!=Sketcher::Constraint::GeoUndef || (*itc)->Second==-1 || (*itc)->Second==-2) // not x, y axes or origin (*itc)->Second-=(addedGeometries+1); if((*itc)->Third!=Sketcher::Constraint::GeoUndef || (*itc)->Third==-1 || (*itc)->Third==-2) // not x, y axes or origin (*itc)->Third-=(addedGeometries+1); } mirrorsketch->addGeometry(mirrorgeo); mirrorsketch->addConstraints(mirrorconstr); delete tempsketch; } doCommand(Gui,"App.activeDocument().recompute()"); }