void TaskTransformedParameters::fillPlanesCombo(ComboLinks &combolinks, Part::Part2DObject* sketch) { combolinks.clear(); //add sketch axes if (sketch){ combolinks.addLink(sketch,"V_Axis",QObject::tr("Vertical sketch axis")); combolinks.addLink(sketch,"H_Axis",QObject::tr("Horizontal sketch axis")); for (int i=0; i < sketch->getAxisCount(); i++) { QString itemText = tr("Construction line %1").arg(i+1); std::stringstream sub; sub << "Axis" << i; combolinks.addLink(sketch,sub.str(),itemText); } } //add part baseplanes App::DocumentObject* obj = getObject(); PartDesign::Body * body = PartDesign::Body::findBodyOf ( obj ); if (body) { try { App::Origin* orig = body->getOrigin(); combolinks.addLink(orig->getXY(),"",tr("Base XY plane")); combolinks.addLink(orig->getYZ(),"",tr("Base YZ plane")); combolinks.addLink(orig->getXZ(),"",tr("Base XZ plane")); } catch (const Base::Exception &ex) { Base::Console().Error ("%s\n", ex.what() ); } } //add "Select reference" combolinks.addLink(0,std::string(),tr("Select reference...")); }
void TaskDatumParameters::resetViewMode() { //end temporary view mode of coordinate system PartDesign::Body * body = PartDesign::Body::findBodyOf(DatumView->getObject()); if (body) { try { App::Origin *origin = body->getOrigin(); ViewProviderOrigin* vpOrigin; vpOrigin = static_cast<ViewProviderOrigin*>(Gui::Application::Instance->getViewProvider(origin)); vpOrigin->resetTemporaryVisibility(); } catch (const Base::Exception &ex) { Base::Console().Error("%s\n", ex.what()); } } DatumView->setPickable(true); }
TaskRevolutionParameters::~TaskRevolutionParameters() { //hide the parts coordinate system axis for selection PartDesign::Body * body = PartDesign::Body::findBodyOf ( vp->getObject() ); if ( body ) { try { App::Origin *origin = body->getOrigin(); ViewProviderOrigin* vpOrigin; vpOrigin = static_cast<ViewProviderOrigin*>(Gui::Application::Instance->getViewProvider(origin)); vpOrigin->resetTemporaryVisibility(); } catch (const Base::Exception &ex) { Base::Console().Error ("%s\n", ex.what () ); } } delete ui; for(size_t i = 0 ; i < axesInList.size() ; i++ ){ delete axesInList[i]; } }
bool ReferenceSelection::allow(App::Document* pDoc, App::DocumentObject* pObj, const char* sSubName) { // TODO review this function (2015-09-04, Fat-Zer) PartDesign::Body *body; App::GeoFeatureGroup *geoGroup; if ( support ) { body = PartDesign::Body::findBodyOf (support); } else { body = PartDesignGui::getBody (false); } if ( body ) { // Search for Part of the body geoGroup = App::GeoFeatureGroup::getGroupOfObject ( body ) ; } else if ( support ) { // if no body search part for support geoGroup = App::GeoFeatureGroup::getGroupOfObject ( support ) ; } else { // fallback to active part geoGroup = PartDesignGui::getActivePart ( ); } // Don't allow selection in other document if ( support && pDoc != support->getDocument() ) { return false; } // Enable selection from origin of current part/ if ( pObj->getTypeId().isDerivedFrom(App::OriginFeature::getClassTypeId()) ) { bool fits = false; if ( plane && pObj->getTypeId().isDerivedFrom(App::Plane::getClassTypeId()) ) { fits = true; } else if ( edge && pObj->getTypeId().isDerivedFrom(App::Line::getClassTypeId()) ) { fits = true; } if (fits) { // check that it is actually belongs to the choosen body or part try { // here are some throwers if (body) { if (body->getOrigin ()->hasObject (pObj) ) { return true; } } else if (geoGroup && geoGroup->isDerivedFrom ( App::OriginGroup::getClassTypeId () ) ) { if ( static_cast<App::OriginGroup *>(geoGroup)->getOrigin ()->hasObject (pObj) ) { return true; } } } catch (const Base::Exception) { } } return false; // The Plane/Axis doesn't fits our needs } if (pObj->getTypeId().isDerivedFrom(Part::Datum::getClassTypeId())) { if (!body) { // Allow selecting Part::Datum features from the active Body return false; } else if (!allowOtherBody && !body->hasFeature(pObj)) { return false; } if (plane && (pObj->getTypeId().isDerivedFrom(PartDesign::Plane::getClassTypeId()))) return true; if (edge && (pObj->getTypeId().isDerivedFrom(PartDesign::Line::getClassTypeId()))) return true; if (point && (pObj->getTypeId().isDerivedFrom(PartDesign::Point::getClassTypeId()))) return true; return false; } // Handle selection of geometry elements if (!sSubName || sSubName[0] == '\0') return false; if (!allowOtherBody) { if (support == NULL) return false; if (pObj != support) return false; } std::string subName(sSubName); if (edge && subName.size() > 4 && subName.substr(0,4) == "Edge") { const Part::TopoShape &shape = static_cast<const Part::Feature*>(pObj)->Shape.getValue(); TopoDS_Shape sh = shape.getSubShape(subName.c_str()); const TopoDS_Edge& edge = TopoDS::Edge(sh); if (!edge.IsNull()) { if (planar) { BRepAdaptor_Curve adapt(edge); if (adapt.GetType() == GeomAbs_Line) return true; } else { return true; } } } if (plane && subName.size() > 4 && subName.substr(0,4) == "Face") { const Part::TopoShape &shape = static_cast<const Part::Feature*>(pObj)->Shape.getValue(); TopoDS_Shape sh = shape.getSubShape(subName.c_str()); const TopoDS_Face& face = TopoDS::Face(sh); if (!face.IsNull()) { if (planar) { BRepAdaptor_Surface adapt(face); if (adapt.GetType() == GeomAbs_Plane) return true; } else { return true; } } } if (point && subName.size() > 6 && subName.substr(0,6) == "Vertex") { return true; } return false; }
TaskRevolutionParameters::TaskRevolutionParameters(PartDesignGui::ViewProvider* RevolutionView, QWidget *parent) : TaskSketchBasedParameters(RevolutionView, parent, "PartDesign_Revolution",tr("Revolution parameters")) { // we need a separate container widget to add all controls to proxy = new QWidget(this); ui = new Ui_TaskRevolutionParameters(); ui->setupUi(proxy); QMetaObject::connectSlotsByName(this); connect(ui->revolveAngle, SIGNAL(valueChanged(double)), this, SLOT(onAngleChanged(double))); connect(ui->axis, SIGNAL(activated(int)), this, SLOT(onAxisChanged(int))); connect(ui->checkBoxMidplane, SIGNAL(toggled(bool)), this, SLOT(onMidplane(bool))); connect(ui->checkBoxReversed, SIGNAL(toggled(bool)), this, SLOT(onReversed(bool))); connect(ui->checkBoxUpdateView, SIGNAL(toggled(bool)), this, SLOT(onUpdateView(bool))); this->groupLayout()->addWidget(proxy); // Temporarily prevent unnecessary feature recomputes ui->revolveAngle->blockSignals(true); ui->axis->blockSignals(true); ui->checkBoxMidplane->blockSignals(true); ui->checkBoxReversed->blockSignals(true); //bind property mirrors PartDesign::ProfileBased* pcFeat = static_cast<PartDesign::ProfileBased*>(vp->getObject()); if (pcFeat->isDerivedFrom(PartDesign::Revolution::getClassTypeId())) { PartDesign::Revolution* rev = static_cast<PartDesign::Revolution*>(vp->getObject()); this->propAngle = &(rev->Angle); this->propMidPlane = &(rev->Midplane); this->propReferenceAxis = &(rev->ReferenceAxis); this->propReversed = &(rev->Reversed); } else { assert(pcFeat->isDerivedFrom(PartDesign::Groove::getClassTypeId())); PartDesign::Groove* rev = static_cast<PartDesign::Groove*>(vp->getObject()); this->propAngle = &(rev->Angle); this->propMidPlane = &(rev->Midplane); this->propReferenceAxis = &(rev->ReferenceAxis); this->propReversed = &(rev->Reversed); } double l = propAngle->getValue(); bool mirrored = propMidPlane->getValue(); bool reversed = propReversed->getValue(); ui->revolveAngle->setValue(l); blockUpdate = false; updateUI(); ui->checkBoxMidplane->setChecked(mirrored); ui->checkBoxReversed->setChecked(reversed); PartDesign::ProfileBased* sketchBased = static_cast<PartDesign::ProfileBased*>(vp->getObject()); // TODO This is quite ugly better redo it (2015-11-02, Fat-Zer) if ( sketchBased->isDerivedFrom(PartDesign::Revolution::getClassTypeId() ) ) { ui->revolveAngle->bind(static_cast<PartDesign::Revolution *> ( sketchBased )->Angle); } else if ( sketchBased->isDerivedFrom(PartDesign::Groove::getClassTypeId() ) ) { ui->revolveAngle->bind(static_cast<PartDesign::Groove *> ( sketchBased )->Angle); } ui->revolveAngle->blockSignals(false); ui->axis->blockSignals(false); ui->checkBoxMidplane->blockSignals(false); ui->checkBoxReversed->blockSignals(false); setFocus (); //show the parts coordinate system axis for selection PartDesign::Body * body = PartDesign::Body::findBodyOf ( vp->getObject () ); if(body) { try { App::Origin *origin = body->getOrigin(); ViewProviderOrigin* vpOrigin; vpOrigin = static_cast<ViewProviderOrigin*>(Gui::Application::Instance->getViewProvider(origin)); vpOrigin->setTemporaryVisibility(true, false); } catch (const Base::Exception &ex) { Base::Console().Error ("%s\n", ex.what () ); } } }
void TaskRevolutionParameters::fillAxisCombo(bool forceRefill) { // TODO share the code with TaskTransformedParameters (2015-08-31, Fat-Zer) bool oldVal_blockUpdate = blockUpdate; blockUpdate = true; if(axesInList.size() == 0) forceRefill = true;//not filled yet, full refill if (forceRefill){ ui->axis->clear(); for(size_t i = 0 ; i < axesInList.size() ; i++ ){ delete axesInList[i]; } this->axesInList.clear(); //add sketch axes PartDesign::ProfileBased* pcFeat = static_cast<PartDesign::Revolution*>(vp->getObject()); Part::Part2DObject* pcSketch = static_cast<Part::Part2DObject*>(pcFeat->Profile.getValue()); if (pcSketch){ addAxisToCombo(pcSketch,"V_Axis",QObject::tr("Vertical sketch axis")); addAxisToCombo(pcSketch,"H_Axis",QObject::tr("Horizontal sketch axis")); for (int i=0; i < pcSketch->getAxisCount(); i++) { QString itemText = QObject::tr("Construction line %1").arg(i+1); std::stringstream sub; sub << "Axis" << i; addAxisToCombo(pcSketch,sub.str(),itemText); } } //add part axes App::DocumentObject* obj = vp->getObject(); PartDesign::Body * body = PartDesign::Body::findBodyOf ( obj ); if (body) { try { App::Origin* orig = body->getOrigin(); addAxisToCombo(orig->getX(),"",tr("Base X axis")); addAxisToCombo(orig->getY(),"",tr("Base Y axis")); addAxisToCombo(orig->getZ(),"",tr("Base Z axis")); } catch (const Base::Exception &ex) { Base::Console().Error ("%s\n", ex.what() ); } } //add "Select reference" addAxisToCombo(0,std::string(),tr("Select reference...")); }//endif forceRefill //add current link, if not in list //first, figure out the item number for current axis int indexOfCurrent = -1; App::DocumentObject* ax = propReferenceAxis->getValue(); const std::vector<std::string> &subList = propReferenceAxis->getSubValues(); for(size_t i = 0 ; i < axesInList.size() ; i++) { if(ax == axesInList[i]->getValue() && subList == axesInList[i]->getSubValues()) indexOfCurrent = i; } if ( indexOfCurrent == -1 && ax ){ assert(subList.size() <= 1); std::string sub; if (subList.size()>0) sub = subList[0]; addAxisToCombo(ax, sub, getRefStr(ax, subList)); indexOfCurrent = axesInList.size()-1; } //highlight current. if (indexOfCurrent != -1) ui->axis->setCurrentIndex(indexOfCurrent); blockUpdate = oldVal_blockUpdate; }
void ViewProviderBody::updateOriginDatumSize () { PartDesign::Body *body = static_cast<PartDesign::Body *> ( getObject() ); // Use different bounding boxes for datums and for origins: Gui::Document* gdoc = Gui::Application::Instance->getDocument(getObject()->getDocument()); if(!gdoc) return; Gui::MDIView* view = gdoc->getViewOfViewProvider(this); if(!view) return; Gui::View3DInventorViewer* viewer = static_cast<Gui::View3DInventor*>(view)->getViewer(); SoGetBoundingBoxAction bboxAction(viewer->getSoRenderManager()->getViewportRegion()); const auto & model = body->getFullModel (); // BBox for Datums is calculated from all visible objects but treating datums as their basepoints only SbBox3f bboxDatums = ViewProviderDatum::getRelevantBoundBox ( bboxAction, model ); // BBox for origin should take into account datums size also SbBox3f bboxOrigins = bboxDatums; for(App::DocumentObject* obj : model) { if ( obj->isDerivedFrom ( Part::Datum::getClassTypeId () ) ) { ViewProvider *vp = Gui::Application::Instance->getViewProvider(obj); if (!vp) { continue; } ViewProviderDatum *vpDatum = static_cast <ViewProviderDatum *> (vp) ; vpDatum->setExtents ( bboxDatums ); bboxAction.apply ( vp->getRoot () ); bboxOrigins.extendBy ( bboxAction.getBoundingBox () ); } } // get the bounding box values SbVec3f max = bboxOrigins.getMax(); SbVec3f min = bboxOrigins.getMin(); // obtain an Origin and it's ViewProvider App::Origin* origin = 0; Gui::ViewProviderOrigin* vpOrigin = 0; try { origin = body->getOrigin (); assert (origin); Gui::ViewProvider *vp = Gui::Application::Instance->getViewProvider(origin); if (!vp) { throw Base::Exception ("No view provider linked to the Origin"); } assert ( vp->isDerivedFrom ( Gui::ViewProviderOrigin::getClassTypeId () ) ); vpOrigin = static_cast <Gui::ViewProviderOrigin *> ( vp ); } catch (const Base::Exception &ex) { Base::Console().Error ("%s\n", ex.what() ); return; } // calculate the desired origin size Base::Vector3d size; for (uint_fast8_t i=0; i<3; i++) { size[i] = std::max ( fabs ( max[i] ), fabs ( min[i] ) ); if (size[i] < Precision::Confusion() ) { size[i] = Gui::ViewProviderOrigin::defaultSize(); } } vpOrigin->Size.setValue ( size*1.2 ); }
TaskDatumParameters::TaskDatumParameters(ViewProviderDatum *DatumView,QWidget *parent) : TaskBox(Gui::BitmapFactory().pixmap((QString::fromLatin1("PartDesign_") + DatumView->datumType).toLatin1()), DatumView->datumType + tr(" parameters"), true, parent), DatumView(DatumView) { // we need a separate container widget to add all controls to proxy = new QWidget(this); ui = new Ui_TaskDatumParameters(); ui->setupUi(proxy); QMetaObject::connectSlotsByName(this); connect(ui->superplacementX, SIGNAL(valueChanged(double)), this, SLOT(onSuperplacementXChanged(double))); connect(ui->superplacementY, SIGNAL(valueChanged(double)), this, SLOT(onSuperplacementYChanged(double))); connect(ui->superplacementZ, SIGNAL(valueChanged(double)), this, SLOT(onSuperplacementZChanged(double))); connect(ui->superplacementYaw, SIGNAL(valueChanged(double)), this, SLOT(onSuperplacementYawChanged(double))); connect(ui->superplacementPitch, SIGNAL(valueChanged(double)), this, SLOT(onSuperplacementPitchChanged(double))); connect(ui->superplacementRoll, SIGNAL(valueChanged(double)), this, SLOT(onSuperplacementRollChanged(double))); connect(ui->checkBoxFlip, SIGNAL(toggled(bool)), this, SLOT(onCheckFlip(bool))); connect(ui->buttonRef1, SIGNAL(clicked(bool)), this, SLOT(onButtonRef1(bool))); connect(ui->lineRef1, SIGNAL(textEdited(QString)), this, SLOT(onRefName1(QString))); connect(ui->buttonRef2, SIGNAL(clicked(bool)), this, SLOT(onButtonRef2(bool))); connect(ui->lineRef2, SIGNAL(textEdited(QString)), this, SLOT(onRefName2(QString))); connect(ui->buttonRef3, SIGNAL(clicked(bool)), this, SLOT(onButtonRef3(bool))); connect(ui->lineRef3, SIGNAL(textEdited(QString)), this, SLOT(onRefName3(QString))); connect(ui->buttonRef4, SIGNAL(clicked(bool)), this, SLOT(onButtonRef4(bool))); connect(ui->lineRef4, SIGNAL(textEdited(QString)), this, SLOT(onRefName4(QString))); connect(ui->listOfModes,SIGNAL(itemSelectionChanged()), this, SLOT(onModeSelect())); this->groupLayout()->addWidget(proxy); // Temporarily prevent unnecessary feature recomputes ui->checkBoxFlip->blockSignals(true); ui->buttonRef1->blockSignals(true); ui->lineRef1->blockSignals(true); ui->buttonRef2->blockSignals(true); ui->lineRef2->blockSignals(true); ui->buttonRef3->blockSignals(true); ui->lineRef3->blockSignals(true); ui->buttonRef4->blockSignals(true); ui->lineRef4->blockSignals(true); ui->listOfModes->blockSignals(true); // Get the feature data Part::Datum* pcDatum = static_cast<Part::Datum*>(DatumView->getObject()); //std::vector<App::DocumentObject*> refs = pcDatum->Support.getValues(); std::vector<std::string> refnames = pcDatum->Support.getSubValues(); ui->checkBoxFlip->setChecked(pcDatum->MapReversed.getValue()); std::vector<QString> refstrings; makeRefStrings(refstrings, refnames); ui->lineRef1->setText(refstrings[0]); ui->lineRef1->setProperty("RefName", QByteArray(refnames[0].c_str())); ui->lineRef2->setText(refstrings[1]); ui->lineRef2->setProperty("RefName", QByteArray(refnames[1].c_str())); ui->lineRef3->setText(refstrings[2]); ui->lineRef3->setProperty("RefName", QByteArray(refnames[2].c_str())); ui->lineRef4->setText(refstrings[3]); ui->lineRef4->setProperty("RefName", QByteArray(refnames[3].c_str())); // activate and de-activate dialog elements as appropriate ui->checkBoxFlip->blockSignals(false); ui->buttonRef1->blockSignals(false); ui->lineRef1->blockSignals(false); ui->buttonRef2->blockSignals(false); ui->lineRef2->blockSignals(false); ui->buttonRef3->blockSignals(false); ui->lineRef3->blockSignals(false); ui->buttonRef4->blockSignals(false); ui->lineRef4->blockSignals(false); ui->listOfModes->blockSignals(false); this->iActiveRef = 0; if (pcDatum->Support.getSize() == 0){ autoNext = true; } else { autoNext = false; } ui->superplacementX->bind(App::ObjectIdentifier::parse(pcDatum,std::string("superPlacement.Base.x"))); ui->superplacementY->bind(App::ObjectIdentifier::parse(pcDatum,std::string("superPlacement.Base.y"))); ui->superplacementZ->bind(App::ObjectIdentifier::parse(pcDatum,std::string("superPlacement.Base.z"))); visibilityAutomation(true); updateSuperplacementUI(); updateReferencesUI(); updateListOfModes(eMapMode(pcDatum->MapMode.getValue())); updatePreview(); //temporary show coordinate systems for selection PartDesign::Body * body = PartDesign::Body::findBodyOf(DatumView->getObject()); if (body) { try { App::Origin *origin = body->getOrigin(); ViewProviderOrigin* vpOrigin; vpOrigin = static_cast<ViewProviderOrigin*>(Gui::Application::Instance->getViewProvider(origin)); vpOrigin->setTemporaryVisibility(true, true); } catch (const Base::Exception &ex) { Base::Console().Error ("%s\n", ex.what () ); } } DatumView->setPickable(false); Gui::Selection().addSelectionGate(new NoDependentsSelection(DatumView->getObject(), true, true, true, true)); // connect object deletion with slot auto bnd = boost::bind(&TaskDatumParameters::objectDeleted, this, _1); Gui::Document* document = Gui::Application::Instance->getDocument(DatumView->getObject()->getDocument()); connectDelObject = document->signalDeletedObject.connect(bnd); }