1
/***************************************************************************
2
* Copyright (c) 2019 Manuel Apeltauer, direkt cnc-systeme GmbH *
4
* This file is part of the FreeCAD CAx development system. *
6
* This library is free software; you can redistribute it and/or *
7
* modify it under the terms of the GNU Library General Public *
8
* License as published by the Free Software Foundation; either *
9
* version 2 of the License, or (at your option) any later version. *
11
* This library is distributed in the hope that it will be useful, *
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14
* GNU Library General Public License for more details. *
16
* You should have received a copy of the GNU Library General Public *
17
* License along with this library; see the file COPYING.LIB. If not, *
18
* write to the Free Software Foundation, Inc., 59 Temple Place, *
19
* Suite 330, Boston, MA 02111-1307, USA *
21
***************************************************************************/
23
#include "PreCompiled.h"
25
#include <BRep_Tool.hxx>
26
#include <BRepBuilderAPI_MakeEdge.hxx>
27
#include <BRepBuilderAPI_MakeFace.hxx>
28
#include <BRepBuilderAPI_Transform.hxx>
29
#include <BRepCheck_Analyzer.hxx>
30
#include <BRepExtrema_DistShapeShape.hxx>
31
#include <BRepPrimAPI_MakePrism.hxx>
32
#include <BRepProj_Projection.hxx>
34
#include <ShapeAnalysis.hxx>
35
#include <ShapeAnalysis_FreeBounds.hxx>
36
#include <ShapeFix_Face.hxx>
37
#include <ShapeFix_Wire.hxx>
38
#include <ShapeFix_Wireframe.hxx>
40
#include <TopExp_Explorer.hxx>
41
#include <TopoDS_Builder.hxx>
42
#include <TopoDS_Edge.hxx>
43
#include <TopoDS_Face.hxx>
46
#include <App/Document.h>
47
#include <Gui/BitmapFactory.h>
48
#include <Gui/CommandT.h>
49
#include <Gui/MainWindow.h>
50
#include <Gui/View3DInventor.h>
51
#include <Gui/View3DInventorViewer.h>
52
#include <Gui/Application.h>
53
#include <Gui/SelectionObject.h>
54
#include <Inventor/SbVec3d.h>
56
#include "DlgProjectionOnSurface.h"
57
#include "ui_DlgProjectionOnSurface.h"
58
#include "ViewProviderExt.h"
61
using namespace PartGui;
64
//////////////////////////////////////////////////////////////////////////
65
class EdgeSelection: public Gui::SelectionFilterGate
68
bool canSelect = false;
71
: Gui::SelectionFilterGate(nullPointer())
74
bool allow(App::Document* /*pDoc*/, App::DocumentObject* iPObj, const char* sSubName) override
76
auto aPart = dynamic_cast<Part::Feature*>(iPObj);
83
std::string subName(sSubName);
84
if (subName.empty()) {
88
auto subShape = aPart->Shape.getShape().getSubShape(sSubName);
89
if (subShape.IsNull()) {
92
auto type = subShape.ShapeType();
93
return (type == TopAbs_EDGE);
96
//////////////////////////////////////////////////////////////////////////
97
//////////////////////////////////////////////////////////////////////////
98
class FaceSelection: public Gui::SelectionFilterGate
101
bool canSelect = false;
104
: Gui::SelectionFilterGate(nullPointer())
107
bool allow(App::Document* /*pDoc*/, App::DocumentObject* iPObj, const char* sSubName) override
109
auto aPart = dynamic_cast<Part::Feature*>(iPObj);
116
std::string subName(sSubName);
117
if (subName.empty()) {
121
auto subShape = aPart->Shape.getShape().getSubShape(sSubName, true);
122
if (subShape.IsNull()) {
125
auto type = subShape.ShapeType();
126
return (type == TopAbs_FACE);
129
//////////////////////////////////////////////////////////////////////////
132
DlgProjectionOnSurface::DlgProjectionOnSurface(QWidget* parent)
134
, ui(new Ui::DlgProjectionOnSurface)
135
, m_projectionObjectName(tr("Projection Object"))
136
, filterEdge(nullptr)
137
, filterFace(nullptr)
142
ui->pushButtonAddEdge->setCheckable(true);
143
ui->pushButtonAddFace->setCheckable(true);
144
ui->pushButtonAddProjFace->setCheckable(true);
145
ui->pushButtonAddWire->setCheckable(true);
147
m_guiObjectVec.push_back(ui->pushButtonAddEdge);
148
m_guiObjectVec.push_back(ui->pushButtonAddFace);
149
m_guiObjectVec.push_back(ui->pushButtonAddProjFace);
150
m_guiObjectVec.push_back(ui->pushButtonDirX);
151
m_guiObjectVec.push_back(ui->pushButtonDirY);
152
m_guiObjectVec.push_back(ui->pushButtonDirZ);
153
m_guiObjectVec.push_back(ui->pushButtonGetCurrentCamDir);
154
m_guiObjectVec.push_back(ui->radioButtonShowAll);
155
m_guiObjectVec.push_back(ui->radioButtonFaces);
156
m_guiObjectVec.push_back(ui->radioButtonEdges);
157
m_guiObjectVec.push_back(ui->pushButtonAddWire);
159
get_camera_direction();
160
disable_ui_elements(m_guiObjectVec, ui->pushButtonAddProjFace);
162
m_partDocument = App::GetApplication().getActiveDocument();
163
if (!m_partDocument) {
164
throw Base::ValueError(QString(tr("Have no active document!!!")).toUtf8());
166
this->attachDocument(m_partDocument);
167
m_partDocument->openTransaction("Project on surface");
168
m_projectionObject = dynamic_cast<Part::Feature*>(
169
m_partDocument->addObject("Part::Feature", "Projection Object"));
170
if (!m_projectionObject) {
171
throw Base::ValueError(QString(tr("Can not create a projection object!!!")).toUtf8());
173
m_projectionObject->Label.setValue(std::string(m_projectionObjectName.toUtf8()).c_str());
174
onRadioButtonShowAllClicked();
175
m_lastDepthVal = ui->doubleSpinBoxSolidDepth->value();
178
DlgProjectionOnSurface::~DlgProjectionOnSurface()
181
for (const auto& it : m_projectionSurfaceVec) {
183
higlight_object(it.partFeature, it.partName, false, 0);
185
catch (Standard_NoSuchObject& e) {
186
Base::Console().Warning("DlgProjectionOnSurface::~DlgProjectionOnSurface: %s",
187
e.GetMessageString());
189
auto vp = dynamic_cast<PartGui::ViewProviderPartExt*>(
190
Gui::Application::Instance->getViewProvider(it.partFeature));
192
vp->Selectable.setValue(it.is_selectable);
193
vp->Transparency.setValue(it.transparency);
196
for (const auto& it : m_shapeVec) {
198
higlight_object(it.partFeature, it.partName, false, 0);
200
catch (Standard_NoSuchObject& e) {
201
Base::Console().Warning("DlgProjectionOnSurface::~DlgProjectionOnSurface: %s",
202
e.GetMessageString());
205
Gui::Selection().rmvSelectionGate();
208
void PartGui::DlgProjectionOnSurface::setupConnections()
211
connect(ui->pushButtonAddFace,
212
&QPushButton::clicked,
214
&DlgProjectionOnSurface::onPushButtonAddFaceClicked);
215
connect(ui->pushButtonAddEdge,
216
&QPushButton::clicked,
218
&DlgProjectionOnSurface::onPushButtonAddEdgeClicked);
219
connect(ui->pushButtonGetCurrentCamDir,
220
&QPushButton::clicked,
222
&DlgProjectionOnSurface::onPushButtonGetCurrentCamDirClicked);
223
connect(ui->pushButtonDirX,
224
&QPushButton::clicked,
226
&DlgProjectionOnSurface::onPushButtonDirXClicked);
227
connect(ui->pushButtonDirY,
228
&QPushButton::clicked,
230
&DlgProjectionOnSurface::onPushButtonDirYClicked);
231
connect(ui->pushButtonDirZ,
232
&QPushButton::clicked,
234
&DlgProjectionOnSurface::onPushButtonDirZClicked);
235
connect(ui->pushButtonAddProjFace,
236
&QPushButton::clicked,
238
&DlgProjectionOnSurface::onPushButtonAddProjFaceClicked);
239
connect(ui->radioButtonShowAll,
240
&QRadioButton::clicked,
242
&DlgProjectionOnSurface::onRadioButtonShowAllClicked);
243
connect(ui->radioButtonFaces,
244
&QRadioButton::clicked,
246
&DlgProjectionOnSurface::onRadioButtonFacesClicked);
247
connect(ui->radioButtonEdges,
248
&QRadioButton::clicked,
250
&DlgProjectionOnSurface::onRadioButtonEdgesClicked);
251
connect(ui->doubleSpinBoxExtrudeHeight,
252
qOverload<double>(&QDoubleSpinBox::valueChanged),
254
&DlgProjectionOnSurface::onDoubleSpinBoxExtrudeHeightValueChanged);
255
connect(ui->pushButtonAddWire,
256
&QPushButton::clicked,
258
&DlgProjectionOnSurface::onPushButtonAddWireClicked);
259
connect(ui->doubleSpinBoxSolidDepth,
260
qOverload<double>(&QDoubleSpinBox::valueChanged),
262
&DlgProjectionOnSurface::onDoubleSpinBoxSolidDepthValueChanged);
266
void PartGui::DlgProjectionOnSurface::slotDeletedDocument(const App::Document& Doc)
268
if (m_partDocument == &Doc) {
269
m_partDocument = nullptr;
270
m_projectionObject = nullptr;
274
void PartGui::DlgProjectionOnSurface::slotDeletedObject(const App::DocumentObject& Obj)
276
if (m_projectionObject == &Obj) {
277
m_projectionObject = nullptr;
281
void PartGui::DlgProjectionOnSurface::apply()
283
if (m_partDocument) {
284
m_partDocument->commitTransaction();
288
void PartGui::DlgProjectionOnSurface::reject()
290
if (m_partDocument) {
291
m_partDocument->abortTransaction();
295
void PartGui::DlgProjectionOnSurface::onPushButtonAddFaceClicked()
297
if (ui->pushButtonAddFace->isChecked()) {
298
m_currentSelection = "add_face";
299
disable_ui_elements(m_guiObjectVec, ui->pushButtonAddFace);
301
filterFace = new FaceSelection();
302
Gui::Selection().addSelectionGate(filterFace);
306
m_currentSelection = "";
307
enable_ui_elements(m_guiObjectVec, nullptr);
308
Gui::Selection().rmvSelectionGate();
309
filterFace = nullptr;
313
void PartGui::DlgProjectionOnSurface::onPushButtonAddEdgeClicked()
315
if (ui->pushButtonAddEdge->isChecked()) {
316
m_currentSelection = "add_edge";
317
disable_ui_elements(m_guiObjectVec, ui->pushButtonAddEdge);
319
filterEdge = new EdgeSelection();
320
Gui::Selection().addSelectionGate(filterEdge);
322
ui->radioButtonEdges->setChecked(true);
323
onRadioButtonEdgesClicked();
326
m_currentSelection = "";
327
enable_ui_elements(m_guiObjectVec, nullptr);
328
Gui::Selection().rmvSelectionGate();
329
filterEdge = nullptr;
333
void PartGui::DlgProjectionOnSurface::onPushButtonGetCurrentCamDirClicked()
335
get_camera_direction();
338
void PartGui::DlgProjectionOnSurface::onPushButtonDirXClicked()
340
set_xyz_dir_spinbox(ui->doubleSpinBoxDirX);
343
void PartGui::DlgProjectionOnSurface::onPushButtonDirYClicked()
345
set_xyz_dir_spinbox(ui->doubleSpinBoxDirY);
348
void PartGui::DlgProjectionOnSurface::onPushButtonDirZClicked()
350
set_xyz_dir_spinbox(ui->doubleSpinBoxDirZ);
353
void PartGui::DlgProjectionOnSurface::onSelectionChanged(const Gui::SelectionChanges& msg)
355
if (msg.Type == Gui::SelectionChanges::AddSelection) {
356
if (m_currentSelection == "add_face" || m_currentSelection == "add_edge"
357
|| m_currentSelection == "add_wire") {
358
store_current_selected_parts(m_shapeVec, 0xff00ff00);
359
create_projection_wire(m_shapeVec);
360
create_projection_face_from_wire(m_shapeVec);
361
create_face_extrude(m_shapeVec);
362
show_projected_shapes(m_shapeVec);
364
else if (m_currentSelection == "add_projection_surface") {
365
m_projectionSurfaceVec.clear();
366
store_current_selected_parts(m_projectionSurfaceVec, 0xffff0000);
367
if (!m_projectionSurfaceVec.empty()) {
368
auto vp = dynamic_cast<PartGui::ViewProviderPartExt*>(
369
Gui::Application::Instance->getViewProvider(
370
m_projectionSurfaceVec.back().partFeature));
372
vp->Selectable.setValue(false);
373
vp->Transparency.setValue(90);
377
ui->pushButtonAddProjFace->setChecked(false);
378
onPushButtonAddProjFaceClicked();
383
void PartGui::DlgProjectionOnSurface::get_camera_direction()
385
auto mainWindow = Gui::getMainWindow();
387
auto mdiObject = dynamic_cast<Gui::View3DInventor*>(mainWindow->activeWindow());
391
auto camerRotation = mdiObject->getViewer()->getCameraOrientation();
393
SbVec3f lookAt(0, 0, -1);
394
camerRotation.multVec(lookAt, lookAt);
399
lookAt.getValue(valX, valY, valZ);
401
ui->doubleSpinBoxDirX->setValue(valX);
402
ui->doubleSpinBoxDirY->setValue(valY);
403
ui->doubleSpinBoxDirZ->setValue(valZ);
406
void PartGui::DlgProjectionOnSurface::store_current_selected_parts(
407
std::vector<SShapeStore>& iStoreVec,
410
if (!m_partDocument) {
413
std::vector<Gui::SelectionObject> selObj = Gui::Selection().getSelectionEx();
414
if (!selObj.empty()) {
415
for (auto it = selObj.begin(); it != selObj.end(); ++it) {
416
auto aPart = dynamic_cast<Part::Feature*>(it->getObject());
422
SShapeStore currentShapeStore;
423
currentShapeStore.inputShape = aPart->Shape.getShape().getShape();
424
currentShapeStore.partFeature = aPart;
425
currentShapeStore.partName = aPart->getNameInDocument();
427
auto vp = dynamic_cast<PartGui::ViewProviderPartExt*>(
428
Gui::Application::Instance->getViewProvider(aPart));
430
currentShapeStore.is_selectable = vp->Selectable.getValue();
431
currentShapeStore.transparency = vp->Transparency.getValue();
433
if (!it->getSubNames().empty()) {
434
auto parentShape = currentShapeStore.inputShape;
435
for (const auto& itName : selObj.front().getSubNames()) {
436
auto currentShape = aPart->Shape.getShape().getSubShape(itName.c_str());
438
transform_shape_to_global_position(currentShape, aPart);
440
currentShapeStore.inputShape = currentShape;
441
currentShapeStore.partName = itName;
442
auto store = store_part_in_vector(currentShapeStore, iStoreVec);
443
higlight_object(aPart, itName, store, iColor);
444
store_wire_in_vector(currentShapeStore, parentShape, iStoreVec, iColor);
448
transform_shape_to_global_position(currentShapeStore.inputShape,
449
currentShapeStore.partFeature);
450
auto store = store_part_in_vector(currentShapeStore, iStoreVec);
451
higlight_object(aPart, aPart->Shape.getName(), store, iColor);
453
Gui::Selection().clearSelection(m_partDocument->getName());
454
Gui::Selection().rmvPreselect();
460
bool PartGui::DlgProjectionOnSurface::store_part_in_vector(SShapeStore& iCurrentShape,
461
std::vector<SShapeStore>& iStoreVec)
463
if (iCurrentShape.inputShape.IsNull()) {
466
auto currentType = iCurrentShape.inputShape.ShapeType();
467
for (auto it = iStoreVec.begin(); it != iStoreVec.end(); ++it) {
468
if (currentType == TopAbs_FACE) {
469
if (it->aFace.IsSame(iCurrentShape.inputShape)) {
474
else if (currentType == TopAbs_EDGE) {
475
if (it->aEdge.IsSame(iCurrentShape.inputShape)) {
482
if (currentType == TopAbs_FACE) {
483
iCurrentShape.aFace = TopoDS::Face(iCurrentShape.inputShape);
485
else if (currentType == TopAbs_EDGE) {
486
iCurrentShape.aEdge = TopoDS::Edge(iCurrentShape.inputShape);
489
auto valX = ui->doubleSpinBoxDirX->value();
490
auto valY = ui->doubleSpinBoxDirY->value();
491
auto valZ = ui->doubleSpinBoxDirZ->value();
493
iCurrentShape.aProjectionDir = gp_Dir(valX, valY, valZ);
494
if (!m_projectionSurfaceVec.empty()) {
495
iCurrentShape.surfaceToProject = m_projectionSurfaceVec.front().aFace;
497
iStoreVec.push_back(iCurrentShape);
501
void PartGui::DlgProjectionOnSurface::create_projection_wire(
502
std::vector<SShapeStore>& iCurrentShape)
505
if (iCurrentShape.empty()) {
508
for (auto& itCurrentShape : iCurrentShape) {
509
if (m_projectionSurfaceVec.empty()) {
512
if (!itCurrentShape.aProjectedEdgeVec.empty()) {
515
if (!itCurrentShape.aProjectedFace.IsNull()) {
518
if (!itCurrentShape.aProjectedWireVec.empty()) {
522
if (!itCurrentShape.aFace.IsNull()) {
523
get_all_wire_from_face(itCurrentShape);
524
for (const auto& itWire : itCurrentShape.aWireVec) {
525
BRepProj_Projection aProjection(itWire,
526
itCurrentShape.surfaceToProject,
527
itCurrentShape.aProjectionDir);
528
double minDistance = std::numeric_limits<double>::max();
529
TopoDS_Wire wireToTake;
530
for (; aProjection.More(); aProjection.Next()) {
531
auto it = aProjection.Current();
532
BRepExtrema_DistShapeShape distanceMeasure(it, itCurrentShape.aFace);
533
distanceMeasure.Perform();
534
auto currentDistance = distanceMeasure.Value();
535
if (currentDistance > minDistance) {
539
minDistance = currentDistance;
541
auto aWire = sort_and_heal_wire(wireToTake, itCurrentShape.surfaceToProject);
542
itCurrentShape.aProjectedWireVec.push_back(aWire);
545
else if (!itCurrentShape.aEdge.IsNull()) {
546
BRepProj_Projection aProjection(itCurrentShape.aEdge,
547
itCurrentShape.surfaceToProject,
548
itCurrentShape.aProjectionDir);
549
double minDistance = std::numeric_limits<double>::max();
550
TopoDS_Wire wireToTake;
551
for (; aProjection.More(); aProjection.Next()) {
552
auto it = aProjection.Current();
553
BRepExtrema_DistShapeShape distanceMeasure(it, itCurrentShape.aEdge);
554
distanceMeasure.Perform();
555
auto currentDistance = distanceMeasure.Value();
556
if (currentDistance > minDistance) {
560
minDistance = currentDistance;
562
for (TopExp_Explorer aExplorer(wireToTake, TopAbs_EDGE); aExplorer.More();
564
itCurrentShape.aProjectedEdgeVec.push_back(TopoDS::Edge(aExplorer.Current()));
569
catch (const Standard_Failure& error) {
570
std::stringstream ssOcc;
572
throw Base::ValueError(ssOcc.str().c_str());
577
PartGui::DlgProjectionOnSurface::create_compound(const std::vector<SShapeStore>& iShapeVec)
579
if (iShapeVec.empty()) {
583
TopoDS_Compound aCompound;
584
TopoDS_Builder aBuilder;
585
aBuilder.MakeCompound(aCompound);
587
for (const auto& it : iShapeVec) {
588
if (m_currentShowType == "edges") {
589
for (const auto& it2 : it.aProjectedEdgeVec) {
590
aBuilder.Add(aCompound, it2);
592
for (const auto& it2 : it.aProjectedWireVec) {
593
aBuilder.Add(aCompound, it2);
596
else if (m_currentShowType == "faces") {
597
if (it.aProjectedFace.IsNull()) {
598
for (const auto& it2 : it.aProjectedWireVec) {
600
aBuilder.Add(aCompound, it2);
605
aBuilder.Add(aCompound, it.aProjectedFace);
608
else if (m_currentShowType == "all") {
609
if (!it.aProjectedSolid.IsNull()) {
610
aBuilder.Add(aCompound, it.aProjectedSolid);
612
else if (!it.aProjectedFace.IsNull()) {
613
aBuilder.Add(aCompound, it.aProjectedFace);
615
else if (!it.aProjectedWireVec.empty()) {
616
for (const auto& itWire : it.aProjectedWireVec) {
617
if (itWire.IsNull()) {
620
aBuilder.Add(aCompound, itWire);
623
else if (!it.aProjectedEdgeVec.empty()) {
624
for (const auto& itEdge : it.aProjectedEdgeVec) {
625
if (itEdge.IsNull()) {
628
aBuilder.Add(aCompound, itEdge);
633
return {std::move(aCompound)};
636
void PartGui::DlgProjectionOnSurface::show_projected_shapes(
637
const std::vector<SShapeStore>& iShapeStoreVec)
639
if (!m_projectionObject) {
642
auto aCompound = create_compound(iShapeStoreVec);
643
if (aCompound.IsNull()) {
644
if (!m_partDocument) {
647
m_projectionObject->Shape.setValue(TopoDS_Shape());
650
auto currentPlacement = m_projectionObject->Placement.getValue();
651
m_projectionObject->Shape.setValue(aCompound);
652
m_projectionObject->Placement.setValue(currentPlacement);
655
auto vp = dynamic_cast<PartGui::ViewProviderPartExt*>(
656
Gui::Application::Instance->getViewProvider(m_projectionObject));
658
const unsigned int color = 0x8ae23400;
659
vp->LineColor.setValue(color);
660
vp->ShapeAppearance.setDiffuseColor(App::Color(color));
661
vp->PointColor.setValue(color);
662
vp->Transparency.setValue(0);
666
void PartGui::DlgProjectionOnSurface::disable_ui_elements(const std::vector<QWidget*>& iObjectVec,
667
QWidget* iExceptThis)
669
for (auto it : iObjectVec) {
673
if (it == iExceptThis) {
676
it->setDisabled(true);
680
void PartGui::DlgProjectionOnSurface::enable_ui_elements(const std::vector<QWidget*>& iObjectVec,
681
QWidget* iExceptThis)
683
for (auto it : iObjectVec) {
687
if (it == iExceptThis) {
690
it->setEnabled(true);
694
void PartGui::DlgProjectionOnSurface::higlight_object(Part::Feature* iCurrentObject,
695
const std::string& iShapeName,
699
if (!iCurrentObject) {
702
auto partenShape = iCurrentObject->Shape.getShape().getShape();
703
auto subShape = iCurrentObject->Shape.getShape().getSubShape(iShapeName.c_str(), true);
705
TopoDS_Shape currentShape = subShape;
706
if (subShape.IsNull()) {
707
currentShape = partenShape;
710
auto currentShapeType = currentShape.ShapeType();
711
TopTools_IndexedMapOfShape anIndices;
712
TopExp::MapShapes(partenShape, currentShapeType, anIndices);
713
if (anIndices.IsEmpty()) {
716
if (!anIndices.Contains(currentShape)) {
719
auto index = anIndices.FindIndex(currentShape);
722
auto vp = dynamic_cast<PartGui::ViewProviderPartExt*>(
723
Gui::Application::Instance->getViewProvider(iCurrentObject));
725
std::vector<App::Color> colors;
726
App::Color defaultColor;
727
if (currentShapeType == TopAbs_FACE) {
728
colors = vp->ShapeAppearance.getDiffuseColors();
729
defaultColor = colors.front();
731
else if (currentShapeType == TopAbs_EDGE) {
732
colors = vp->LineColorArray.getValues();
733
defaultColor = vp->LineColor.getValue();
736
if (static_cast<Standard_Integer>(colors.size()) != anIndices.Extent()) {
737
colors.resize(anIndices.Extent(), defaultColor);
742
aColor.setPackedValue(iColor);
743
colors.at(index - 1) = aColor;
746
colors.at(index - 1) = defaultColor;
748
if (currentShapeType == TopAbs_FACE) {
749
vp->ShapeAppearance.setDiffuseColors(colors);
751
else if (currentShapeType == TopAbs_EDGE) {
752
vp->LineColorArray.setValues(colors);
757
void PartGui::DlgProjectionOnSurface::get_all_wire_from_face(SShapeStore& ioCurrentSahpe)
759
auto outerWire = ShapeAnalysis::OuterWire(ioCurrentSahpe.aFace);
760
ioCurrentSahpe.aWireVec.push_back(outerWire);
761
for (TopExp_Explorer aExplorer(ioCurrentSahpe.aFace, TopAbs_WIRE); aExplorer.More();
763
auto currentWire = TopoDS::Wire(aExplorer.Current());
764
if (currentWire.IsSame(outerWire)) {
767
ioCurrentSahpe.aWireVec.push_back(currentWire);
771
void PartGui::DlgProjectionOnSurface::create_projection_face_from_wire(
772
std::vector<SShapeStore>& iCurrentShape)
775
if (iCurrentShape.empty()) {
779
for (auto& itCurrentShape : iCurrentShape) {
780
if (itCurrentShape.aFace.IsNull()) {
783
if (itCurrentShape.aProjectedWireVec.empty()) {
786
if (!itCurrentShape.aProjectedFace.IsNull()) {
790
auto surface = BRep_Tool::Surface(itCurrentShape.surfaceToProject);
792
// create a wire of all edges in parametric space on the surface of the face to
794
// --> otherwise BRepBuilderAPI_MakeFace can not make a face from the wire!
795
for (const auto& itWireVec : itCurrentShape.aProjectedWireVec) {
796
std::vector<TopoDS_Shape> edgeVec;
797
for (TopExp_Explorer aExplorer(itWireVec, TopAbs_EDGE); aExplorer.More();
799
auto currentEdge = TopoDS::Edge(aExplorer.Current());
800
edgeVec.push_back(currentEdge);
802
if (edgeVec.empty()) {
806
std::vector<TopoDS_Edge> edgeInParametricSpaceVec;
807
for (auto itEdge : edgeVec) {
808
Standard_Real first {};
809
Standard_Real last {};
810
auto currentCurve = BRep_Tool::CurveOnSurface(TopoDS::Edge(itEdge),
811
itCurrentShape.surfaceToProject,
817
auto edgeInParametricSpace =
818
BRepBuilderAPI_MakeEdge(currentCurve, surface, first, last).Edge();
819
edgeInParametricSpaceVec.push_back(edgeInParametricSpace);
822
sort_and_heal_wire(edgeInParametricSpaceVec, itCurrentShape.surfaceToProject);
823
itCurrentShape.aProjectedWireInParametricSpaceVec.push_back(aWire);
826
// try to create a face from the wires
827
// the first wire is the otherwise
828
// the following wires are the inside wires
829
BRepBuilderAPI_MakeFace faceMaker;
831
for (auto itWireVec : itCurrentShape.aProjectedWireInParametricSpaceVec) {
834
// change the wire direction, otherwise no face is created
835
auto currentWire = TopoDS::Wire(itWireVec.Reversed());
836
if (itCurrentShape.surfaceToProject.Orientation() == TopAbs_REVERSED) {
837
currentWire = itWireVec;
839
faceMaker = BRepBuilderAPI_MakeFace(surface, currentWire);
840
ShapeFix_Face fix(faceMaker.Face());
842
auto aFace = fix.Face();
843
BRepCheck_Analyzer aChecker(aFace);
844
if (!aChecker.IsValid()) {
846
BRepBuilderAPI_MakeFace(surface, TopoDS::Wire(currentWire.Reversed()));
850
// make a copy of the current face maker
851
// if the face fails just try again with the copy
852
TopoDS_Face tempCopy = BRepBuilderAPI_MakeFace(faceMaker.Face()).Face();
853
faceMaker.Add(TopoDS::Wire(itWireVec.Reversed()));
854
ShapeFix_Face fix(faceMaker.Face());
856
auto aFace = fix.Face();
857
BRepCheck_Analyzer aChecker(aFace);
858
if (!aChecker.IsValid()) {
859
faceMaker = BRepBuilderAPI_MakeFace(tempCopy);
860
faceMaker.Add(TopoDS::Wire(itWireVec));
864
// auto doneFlag = faceMaker.IsDone();
865
// auto error = faceMaker.Error();
866
itCurrentShape.aProjectedFace = faceMaker.Face();
869
catch (const Standard_Failure& error) {
870
std::stringstream ssOcc;
872
throw Base::ValueError(ssOcc.str().c_str());
876
TopoDS_Wire PartGui::DlgProjectionOnSurface::sort_and_heal_wire(const TopoDS_Shape& iShape,
877
const TopoDS_Face& iFaceToProject)
879
std::vector<TopoDS_Edge> aEdgeVec;
880
for (TopExp_Explorer aExplorer(iShape, TopAbs_EDGE); aExplorer.More(); aExplorer.Next()) {
881
auto anEdge = TopoDS::Edge(aExplorer.Current());
882
aEdgeVec.push_back(anEdge);
884
return sort_and_heal_wire(aEdgeVec, iFaceToProject);
888
PartGui::DlgProjectionOnSurface::sort_and_heal_wire(const std::vector<TopoDS_Edge>& iEdgeVec,
889
const TopoDS_Face& iFaceToProject)
891
// try to sort and heal all wires
892
// if the wires are not clean making a face will fail!
893
ShapeAnalysis_FreeBounds shapeAnalyzer;
894
Handle(TopTools_HSequenceOfShape) shapeList = new TopTools_HSequenceOfShape;
895
Handle(TopTools_HSequenceOfShape) aWireHandle;
896
Handle(TopTools_HSequenceOfShape) aWireWireHandle;
898
for (const auto& it : iEdgeVec) {
899
shapeList->Append(it);
902
const double tolerance = 0.0001;
903
ShapeAnalysis_FreeBounds::ConnectEdgesToWires(shapeList, tolerance, false, aWireHandle);
904
ShapeAnalysis_FreeBounds::ConnectWiresToWires(aWireHandle, tolerance, false, aWireWireHandle);
905
if (!aWireWireHandle) {
908
for (auto it = 1; it <= aWireWireHandle->Length(); ++it) {
909
auto aShape = TopoDS::Wire(aWireWireHandle->Value(it));
910
ShapeFix_Wire aWireRepair(aShape, iFaceToProject, tolerance);
911
aWireRepair.FixAddCurve3dMode() = 1;
912
aWireRepair.FixAddPCurveMode() = 1;
913
aWireRepair.Perform();
914
// return aWireRepair.Wire();
915
ShapeFix_Wireframe aWireFramFix(aWireRepair.Wire());
916
aWireFramFix.FixWireGaps();
917
aWireFramFix.FixSmallEdges();
918
return TopoDS::Wire(aWireFramFix.Shape());
923
void PartGui::DlgProjectionOnSurface::create_face_extrude(std::vector<SShapeStore>& iCurrentShape)
926
if (iCurrentShape.empty()) {
930
auto height = ui->doubleSpinBoxExtrudeHeight->value();
932
for (auto& itCurrentShape : iCurrentShape) {
933
if (itCurrentShape.aProjectedFace.IsNull()) {
936
if (itCurrentShape.extrudeValue == height) {
940
itCurrentShape.extrudeValue = height;
942
itCurrentShape.aProjectedSolid.Nullify();
945
gp_Vec directionToExtrude(itCurrentShape.aProjectionDir.XYZ());
946
directionToExtrude.Reverse();
947
directionToExtrude.Multiply(height);
948
BRepPrimAPI_MakePrism extrude(itCurrentShape.aProjectedFace, directionToExtrude);
949
itCurrentShape.aProjectedSolid = extrude.Shape();
953
catch (const Standard_Failure& error) {
954
std::stringstream ssOcc;
956
throw Base::ValueError(ssOcc.str().c_str());
960
void PartGui::DlgProjectionOnSurface::store_wire_in_vector(const SShapeStore& iCurrentShape,
961
const TopoDS_Shape& iParentShape,
962
std::vector<SShapeStore>& iStoreVec,
965
if (m_currentSelection != "add_wire") {
968
if (iParentShape.IsNull()) {
971
if (iCurrentShape.inputShape.IsNull()) {
974
auto currentType = iCurrentShape.inputShape.ShapeType();
975
if (currentType != TopAbs_EDGE) {
979
std::vector<TopoDS_Wire> aWireVec;
980
for (TopExp_Explorer aExplorer(iParentShape, TopAbs_WIRE); aExplorer.More(); aExplorer.Next()) {
981
aWireVec.push_back(TopoDS::Wire(aExplorer.Current()));
984
std::vector<TopoDS_Edge> edgeVec;
985
for (const auto& it : aWireVec) {
986
bool edgeExists = false;
987
for (TopExp_Explorer aExplorer(it, TopAbs_EDGE); aExplorer.More(); aExplorer.Next()) {
988
auto currentEdge = TopoDS::Edge(aExplorer.Current());
989
edgeVec.push_back(currentEdge);
990
if (currentEdge.IsSame(iCurrentShape.inputShape)) {
1000
if (edgeVec.empty()) {
1003
TopTools_IndexedMapOfShape indexMap;
1004
TopExp::MapShapes(iParentShape, TopAbs_EDGE, indexMap);
1005
if (indexMap.IsEmpty()) {
1009
for (const auto& it : edgeVec) {
1010
if (it.IsSame(iCurrentShape.inputShape)) {
1013
if (!indexMap.Contains(it)) {
1016
auto index = indexMap.FindIndex(it);
1017
auto newEdgeObject = iCurrentShape;
1018
newEdgeObject.inputShape = it;
1019
newEdgeObject.partName = "Edge" + std::to_string(index);
1021
auto store = store_part_in_vector(newEdgeObject, iStoreVec);
1022
higlight_object(newEdgeObject.partFeature, newEdgeObject.partName, store, iColor);
1026
void PartGui::DlgProjectionOnSurface::set_xyz_dir_spinbox(QDoubleSpinBox* icurrentSpinBox)
1028
auto currentVal = icurrentSpinBox->value();
1030
if (currentVal != 1.0 && currentVal != -1.0) {
1033
else if (currentVal == 1.0) {
1036
else if (currentVal == -1.0) {
1039
ui->doubleSpinBoxDirX->setValue(0);
1040
ui->doubleSpinBoxDirY->setValue(0);
1041
ui->doubleSpinBoxDirZ->setValue(0);
1042
icurrentSpinBox->setValue(newVal);
1045
void PartGui::DlgProjectionOnSurface::transform_shape_to_global_position(TopoDS_Shape& ioShape,
1046
Part::Feature* iPart)
1048
auto currentPos = iPart->Placement.getValue().getPosition();
1049
auto currentRotation = iPart->Placement.getValue().getRotation();
1050
auto globalPlacement = iPart->globalPlacement();
1051
auto globalPosition = globalPlacement.getPosition();
1052
auto globalRotation = globalPlacement.getRotation();
1054
if (currentRotation != globalRotation) {
1055
auto newRotation = globalRotation;
1056
newRotation *= currentRotation.invert();
1058
gp_Trsf aAngleTransform;
1059
Base::Vector3d rotationAxes;
1060
double rotationAngle {};
1061
newRotation.getRawValue(rotationAxes, rotationAngle);
1062
aAngleTransform.SetRotation(gp_Ax1(gp_Pnt(currentPos.x, currentPos.y, currentPos.z),
1063
gp_Dir(rotationAxes.x, rotationAxes.y, rotationAxes.z)),
1065
ioShape = BRepBuilderAPI_Transform(ioShape, aAngleTransform, true).Shape();
1068
if (currentPos != globalPosition) {
1069
gp_Trsf aPosTransform;
1070
aPosTransform.SetTranslation(gp_Pnt(currentPos.x, currentPos.y, currentPos.z),
1071
gp_Pnt(globalPosition.x, globalPosition.y, globalPosition.z));
1072
ioShape = BRepBuilderAPI_Transform(ioShape, aPosTransform, true).Shape();
1076
void PartGui::DlgProjectionOnSurface::onPushButtonAddProjFaceClicked()
1078
if (ui->pushButtonAddProjFace->isChecked()) {
1079
m_currentSelection = "add_projection_surface";
1080
disable_ui_elements(m_guiObjectVec, ui->pushButtonAddProjFace);
1082
filterFace = new FaceSelection();
1083
Gui::Selection().addSelectionGate(filterFace);
1087
m_currentSelection = "";
1088
enable_ui_elements(m_guiObjectVec, nullptr);
1089
Gui::Selection().rmvSelectionGate();
1090
filterFace = nullptr;
1093
void PartGui::DlgProjectionOnSurface::onRadioButtonShowAllClicked()
1095
m_currentShowType = "all";
1096
show_projected_shapes(m_shapeVec);
1099
void PartGui::DlgProjectionOnSurface::onRadioButtonFacesClicked()
1101
m_currentShowType = "faces";
1102
show_projected_shapes(m_shapeVec);
1105
void PartGui::DlgProjectionOnSurface::onRadioButtonEdgesClicked()
1107
m_currentShowType = "edges";
1108
show_projected_shapes(m_shapeVec);
1111
void PartGui::DlgProjectionOnSurface::onDoubleSpinBoxExtrudeHeightValueChanged(double arg1)
1114
create_face_extrude(m_shapeVec);
1115
show_projected_shapes(m_shapeVec);
1118
void PartGui::DlgProjectionOnSurface::onPushButtonAddWireClicked()
1120
if (ui->pushButtonAddWire->isChecked()) {
1121
m_currentSelection = "add_wire";
1122
disable_ui_elements(m_guiObjectVec, ui->pushButtonAddWire);
1124
filterEdge = new EdgeSelection();
1125
Gui::Selection().addSelectionGate(filterEdge);
1127
ui->radioButtonEdges->setChecked(true);
1128
onRadioButtonEdgesClicked();
1131
m_currentSelection = "";
1132
enable_ui_elements(m_guiObjectVec, nullptr);
1133
Gui::Selection().rmvSelectionGate();
1134
filterEdge = nullptr;
1138
void PartGui::DlgProjectionOnSurface::onDoubleSpinBoxSolidDepthValueChanged(double arg1)
1140
auto valX = ui->doubleSpinBoxDirX->value();
1141
auto valY = ui->doubleSpinBoxDirY->value();
1142
auto valZ = ui->doubleSpinBoxDirZ->value();
1144
auto valueToMove = arg1 - m_lastDepthVal;
1145
Base::Vector3d vectorToMove(valX, valY, valZ);
1146
vectorToMove *= valueToMove;
1148
auto placment = m_projectionObject->Placement.getValue();
1149
placment.move(vectorToMove);
1150
m_projectionObject->Placement.setValue(placment);
1152
m_lastDepthVal = ui->doubleSpinBoxSolidDepth->value();
1155
// ---------------------------------------
1157
TaskProjectionOnSurface::TaskProjectionOnSurface()
1158
: widget(new DlgProjectionOnSurface())
1159
, taskbox(new Gui::TaskView::TaskBox(Gui::BitmapFactory().pixmap("Part_ProjectionOnSurface"),
1160
widget->windowTitle(),
1164
taskbox->groupLayout()->addWidget(widget);
1165
Content.push_back(taskbox);
1168
bool TaskProjectionOnSurface::accept()
1174
bool TaskProjectionOnSurface::reject()
1180
void TaskProjectionOnSurface::clicked(int id)
1182
if (id == QDialogButtonBox::Apply) {
1186
catch (Base::AbortException&) {
1191
// ------------------------------------------------------------------------------------------------
1193
DlgProjectOnSurface::DlgProjectOnSurface(Part::ProjectOnSurface* feature, QWidget* parent)
1195
, ui(new Ui::DlgProjectionOnSurface)
1196
, filterEdge(nullptr)
1197
, filterFace(nullptr)
1201
ui->doubleSpinBoxExtrudeHeight->setValue(feature->Height.getValue());
1202
ui->doubleSpinBoxSolidDepth->setValue(feature->Offset.getValue());
1207
ui->pushButtonAddEdge->setCheckable(true);
1208
ui->pushButtonAddFace->setCheckable(true);
1209
ui->pushButtonAddProjFace->setCheckable(true);
1210
ui->pushButtonAddWire->setCheckable(true);
1213
DlgProjectOnSurface::~DlgProjectOnSurface()
1215
if (filterFace || filterEdge) {
1216
Gui::Selection().rmvSelectionGate();
1220
void DlgProjectOnSurface::setupConnections()
1223
connect(ui->pushButtonAddFace, &QPushButton::clicked,
1224
this, &DlgProjectOnSurface::onAddFaceClicked);
1225
connect(ui->pushButtonAddEdge, &QPushButton::clicked,
1226
this, &DlgProjectOnSurface::onAddEdgeClicked);
1227
connect(ui->pushButtonGetCurrentCamDir, &QPushButton::clicked,
1228
this, &DlgProjectOnSurface::onGetCurrentCamDirClicked);
1229
connect(ui->pushButtonDirX, &QPushButton::clicked,
1230
this, &DlgProjectOnSurface::onDirXClicked);
1231
connect(ui->pushButtonDirY, &QPushButton::clicked,
1232
this, &DlgProjectOnSurface::onDirYClicked);
1233
connect(ui->pushButtonDirZ, &QPushButton::clicked,
1234
this, &DlgProjectOnSurface::onDirZClicked);
1235
connect(ui->pushButtonAddProjFace, &QPushButton::clicked,
1236
this, &DlgProjectOnSurface::onAddProjFaceClicked);
1237
connect(ui->radioButtonShowAll, &QRadioButton::clicked,
1238
this, &DlgProjectOnSurface::onShowAllClicked);
1239
connect(ui->radioButtonFaces, &QRadioButton::clicked,
1240
this, &DlgProjectOnSurface::onFacesClicked);
1241
connect(ui->radioButtonEdges, &QRadioButton::clicked,
1242
this, &DlgProjectOnSurface::onEdgesClicked);
1243
connect(ui->doubleSpinBoxExtrudeHeight, qOverload<double>(&QDoubleSpinBox::valueChanged),
1244
this, &DlgProjectOnSurface::onExtrudeHeightValueChanged);
1245
connect(ui->pushButtonAddWire, &QPushButton::clicked,
1246
this, &DlgProjectOnSurface::onAddWireClicked);
1247
connect(ui->doubleSpinBoxSolidDepth, qOverload<double>(&QDoubleSpinBox::valueChanged),
1248
this, &DlgProjectOnSurface::onSolidDepthValueChanged);
1252
void DlgProjectOnSurface::onSelectionChanged(const Gui::SelectionChanges& msg)
1255
if (msg.Type == Gui::SelectionChanges::AddSelection) {
1256
if (selectionMode == SelectionMode::AddFace ||
1257
selectionMode == SelectionMode::AddEdge) {
1260
else if (selectionMode == SelectionMode::AddWire) {
1263
else if (selectionMode == SelectionMode::SupportFace) {
1264
ui->pushButtonAddProjFace->setChecked(false);
1265
setSupportFace(msg);
1266
onAddProjFaceClicked();
1272
void DlgProjectOnSurface::accept()
1274
if (!feature.expired()) {
1275
auto document = feature->getDocument();
1276
document->commitTransaction();
1277
document->recompute();
1281
void DlgProjectOnSurface::reject()
1283
if (!feature.expired()) {
1284
auto document = feature->getDocument();
1285
document->abortTransaction();
1289
void DlgProjectOnSurface::onAddProjFaceClicked()
1291
if (ui->pushButtonAddProjFace->isChecked()) {
1292
selectionMode = SelectionMode::SupportFace;
1294
filterFace = new FaceSelection();
1295
Gui::Selection().addSelectionGate(filterFace);
1299
selectionMode = SelectionMode::None;
1300
Gui::Selection().rmvSelectionGate();
1301
filterFace = nullptr;
1305
void DlgProjectOnSurface::onAddFaceClicked()
1307
if (ui->pushButtonAddFace->isChecked()) {
1308
selectionMode = SelectionMode::AddFace;
1310
filterFace = new FaceSelection();
1311
Gui::Selection().addSelectionGate(filterFace);
1315
selectionMode = SelectionMode::None;
1316
Gui::Selection().rmvSelectionGate();
1317
filterFace = nullptr;
1321
void DlgProjectOnSurface::onAddWireClicked()
1323
if (ui->pushButtonAddWire->isChecked()) {
1324
selectionMode = SelectionMode::AddWire;
1326
filterEdge = new EdgeSelection();
1327
Gui::Selection().addSelectionGate(filterEdge);
1329
ui->radioButtonEdges->setChecked(true);
1333
selectionMode = SelectionMode::None;
1334
Gui::Selection().rmvSelectionGate();
1335
filterEdge = nullptr;
1339
void DlgProjectOnSurface::onAddEdgeClicked()
1341
if (ui->pushButtonAddEdge->isChecked()) {
1342
selectionMode = SelectionMode::AddEdge;
1344
filterEdge = new EdgeSelection();
1345
Gui::Selection().addSelectionGate(filterEdge);
1347
ui->radioButtonEdges->setChecked(true);
1351
selectionMode = SelectionMode::None;
1352
Gui::Selection().rmvSelectionGate();
1353
filterEdge = nullptr;
1357
void DlgProjectOnSurface::onGetCurrentCamDirClicked()
1359
auto mainWindow = Gui::getMainWindow();
1361
auto mdiObject = dynamic_cast<Gui::View3DInventor*>(mainWindow->activeWindow());
1365
auto camerRotation = mdiObject->getViewer()->getCameraOrientation();
1367
SbVec3f lookAt(0, 0, -1);
1368
camerRotation.multVec(lookAt, lookAt);
1373
lookAt.getValue(valX, valY, valZ);
1375
ui->doubleSpinBoxDirX->setValue(valX);
1376
ui->doubleSpinBoxDirY->setValue(valY);
1377
ui->doubleSpinBoxDirZ->setValue(valZ);
1381
void DlgProjectOnSurface::onDirXClicked()
1383
auto currentVal = ui->doubleSpinBoxDirX->value();
1384
ui->doubleSpinBoxDirX->setValue(currentVal > 0 ? -1 : 1);
1385
ui->doubleSpinBoxDirY->setValue(0);
1386
ui->doubleSpinBoxDirZ->setValue(0);
1390
void DlgProjectOnSurface::onDirYClicked()
1392
auto currentVal = ui->doubleSpinBoxDirY->value();
1393
ui->doubleSpinBoxDirX->setValue(0);
1394
ui->doubleSpinBoxDirY->setValue(currentVal > 0 ? -1 : 1);
1395
ui->doubleSpinBoxDirZ->setValue(0);
1399
void DlgProjectOnSurface::onDirZClicked()
1401
auto currentVal = ui->doubleSpinBoxDirZ->value();
1402
ui->doubleSpinBoxDirX->setValue(0);
1403
ui->doubleSpinBoxDirY->setValue(0);
1404
ui->doubleSpinBoxDirZ->setValue(currentVal > 0 ? -1 : 1);
1408
void DlgProjectOnSurface::setDirection()
1410
if (!feature.expired()) {
1411
auto xVal = ui->doubleSpinBoxDirX->value();
1412
auto yVal = ui->doubleSpinBoxDirY->value();
1413
auto zVal = ui->doubleSpinBoxDirZ->value();
1414
feature->Direction.setValue(Base::Vector3d(xVal, yVal, zVal));
1415
feature->recomputeFeature();
1419
void DlgProjectOnSurface::addWire(const Gui::SelectionChanges& msg)
1421
auto isEdgePartOf = [](const TopoDS_Shape& wire, const TopoDS_Shape& edge) {
1422
for (TopExp_Explorer xp(wire, TopAbs_EDGE); xp.More(); xp.Next()) {
1423
if (edge.IsSame(xp.Current())) {
1430
if (selectionMode != SelectionMode::AddWire) {
1434
Gui::SelectionObject selObj(msg);
1435
if (!selObj.hasSubNames()) {
1439
Part::TopoShape part = Part::Feature::getTopoShape(selObj.getObject());
1440
if (part.isNull()) {
1444
std::string subName = selObj.getSubNames().front();
1445
TopoDS_Shape edge = part.getSubShape(subName.c_str(), true);
1446
if (edge.IsNull() || edge.ShapeType() != TopAbs_EDGE) {
1451
const TopoDS_Shape& shape = part.getShape();
1452
for (TopExp_Explorer xp(shape, TopAbs_WIRE); xp.More(); xp.Next()) {
1453
if (isEdgePartOf(xp.Current(), edge)) {
1454
std::string name{"Wire"};
1455
name += std::to_string(index);
1456
addSelection(msg, name);
1463
void DlgProjectOnSurface::addSelection(const Gui::SelectionChanges& msg,
1464
const std::string& subName)
1466
if (!feature.expired()) {
1467
Gui::SelectionObject selObj(msg);
1468
feature->Projection.addValue(selObj.getObject(), {subName});
1472
void DlgProjectOnSurface::addSelection(const Gui::SelectionChanges& msg)
1474
if (!feature.expired()) {
1475
Gui::SelectionObject selObj(msg);
1476
feature->Projection.addValue(selObj.getObject(), selObj.getSubNames());
1480
void DlgProjectOnSurface::setSupportFace(const Gui::SelectionChanges& msg)
1482
Gui::SelectionObject selObj(msg);
1483
if (!feature.expired()) {
1484
feature->SupportFace.setValue(selObj.getObject(), selObj.getSubNames());
1485
feature->recomputeFeature();
1489
void DlgProjectOnSurface::fetchDirection()
1491
if (!feature.expired()) {
1492
auto dir = feature->Direction.getValue();
1493
ui->doubleSpinBoxDirX->setValue(dir.x);
1494
ui->doubleSpinBoxDirY->setValue(dir.y);
1495
ui->doubleSpinBoxDirZ->setValue(dir.z);
1499
void DlgProjectOnSurface::fetchMode()
1501
if (!feature.expired()) {
1502
if (strcmp(feature->Mode.getValueAsString(), Part::ProjectOnSurface::AllMode) == 0) {
1503
ui->radioButtonShowAll->setChecked(true);
1505
else if (strcmp(feature->Mode.getValueAsString(), Part::ProjectOnSurface::FacesMode) == 0) {
1506
ui->radioButtonFaces->setChecked(true);
1508
else if (strcmp(feature->Mode.getValueAsString(), Part::ProjectOnSurface::EdgesMode) == 0) {
1509
ui->radioButtonEdges->setChecked(true);
1514
void DlgProjectOnSurface::onShowAllClicked()
1516
if (!feature.expired()) {
1517
feature->Mode.setValue(Part::ProjectOnSurface::AllMode);
1518
feature->recomputeFeature();
1522
void DlgProjectOnSurface::onFacesClicked()
1524
if (!feature.expired()) {
1525
feature->Mode.setValue(Part::ProjectOnSurface::FacesMode);
1526
feature->recomputeFeature();
1530
void DlgProjectOnSurface::onEdgesClicked()
1532
if (!feature.expired()) {
1533
feature->Mode.setValue(Part::ProjectOnSurface::EdgesMode);
1534
feature->recomputeFeature();
1538
void DlgProjectOnSurface::onExtrudeHeightValueChanged(double value)
1540
if (!feature.expired()) {
1541
feature->Height.setValue(value);
1542
feature->recomputeFeature();
1546
void DlgProjectOnSurface::onSolidDepthValueChanged(double value)
1548
if (!feature.expired()) {
1549
feature->Offset.setValue(value);
1550
feature->recomputeFeature();
1554
// ---------------------------------------
1556
TaskProjectOnSurface::TaskProjectOnSurface(App::Document* doc)
1558
setDocumentName(doc->getName());
1559
doc->openTransaction(QT_TRANSLATE_NOOP("Command", "Project on surface"));
1560
auto obj = doc->addObject("Part::ProjectOnSurface", "Projection");
1561
auto feature = dynamic_cast<Part::ProjectOnSurface*>(obj);
1562
widget = new DlgProjectOnSurface(feature);
1563
taskbox = new Gui::TaskView::TaskBox(Gui::BitmapFactory().pixmap("Part_ProjectionOnSurface"),
1564
widget->windowTitle(), true, nullptr);
1565
taskbox->groupLayout()->addWidget(widget);
1566
Content.push_back(taskbox);
1569
TaskProjectOnSurface::TaskProjectOnSurface(Part::ProjectOnSurface* feature)
1570
: widget(new DlgProjectOnSurface(feature))
1571
, taskbox(new Gui::TaskView::TaskBox(Gui::BitmapFactory().pixmap("Part_ProjectionOnSurface"),
1572
widget->windowTitle(),
1576
taskbox->groupLayout()->addWidget(widget);
1577
Content.push_back(taskbox);
1580
void TaskProjectOnSurface::resetEdit()
1582
std::string document = getDocumentName();
1583
Gui::doCommandT(Gui::Command::Gui, "Gui.getDocument('%s').resetEdit()", document);
1586
bool TaskProjectOnSurface::accept()
1593
bool TaskProjectOnSurface::reject()
1600
#include "moc_DlgProjectionOnSurface.cpp"