1 // Copyright 2001-2018 Crytek GmbH / Crytek Group. All rights reserved.
5 #include "Tools/Select/SelectTool.h"
6 #include "DesignerEditor.h"
7 #include "Core/PolygonDecomposer.h"
11 void WeldTool::Weld(MainContext
& mc
, const BrushVec3
& vSrc
, const BrushVec3
& vTarget
)
13 BrushEdge3D
e(vSrc
, vTarget
);
14 std::vector
<PolygonPtr
> newPolygonList
;
15 std::vector
<PolygonPtr
> unnecessaryPolygonList
;
16 std::vector
<std::pair
<PolygonPtr
, PolygonPtr
>> weldedPolygons
;
18 for (int i
= 0, iPolygonCount(mc
.pModel
->GetPolygonCount()); i
< iPolygonCount
; ++i
)
20 PolygonPtr pPolygon
= mc
.pModel
->GetPolygon(i
);
21 DESIGNER_ASSERT(pPolygon
);
25 int nVertexIndex
= -1;
27 if (pPolygon
->HasEdge(e
, false, &nEdgeIndex
))
29 PolygonPtr pWeldedPolygon
= pPolygon
->Clone();
30 IndexPair edgeIndexPair
= pWeldedPolygon
->GetEdgeIndexPair(nEdgeIndex
);
31 BrushVec3 v0
= pWeldedPolygon
->GetPos(edgeIndexPair
.m_i
[0]);
32 BrushVec3 v1
= pWeldedPolygon
->GetPos(edgeIndexPair
.m_i
[1]);
33 if (Comparison::IsEquivalent(e
.m_v
[0], v1
))
35 std::swap(edgeIndexPair
.m_i
[0], edgeIndexPair
.m_i
[1]);
38 pWeldedPolygon
->SetPos(edgeIndexPair
.m_i
[0], v1
);
39 pWeldedPolygon
->Optimize();
40 weldedPolygons
.push_back(std::pair
<PolygonPtr
, PolygonPtr
>(pPolygon
, pWeldedPolygon
));
42 else if (pPolygon
->HasPosition(e
.m_v
[0], &nVertexIndex
))
44 if (std::abs(pPolygon
->GetPlane().Distance(e
.m_v
[1])) > kDesignerEpsilon
)
46 if (pPolygon
->IsQuad())
48 PolygonPtr pWeldedPolygon
= pPolygon
->Clone();
49 pWeldedPolygon
->SetPos(nVertexIndex
, e
.m_v
[1]);
50 pWeldedPolygon
->AddFlags(ePolyFlag_NonplanarQuad
);
52 pWeldedPolygon
->GetComputedPlane(newPlane
);
53 pWeldedPolygon
->SetPlane(newPlane
);
54 weldedPolygons
.push_back(std::pair
<PolygonPtr
, PolygonPtr
>(pPolygon
, pWeldedPolygon
));
58 PolygonDecomposer decomposer
;
59 std::vector
<PolygonPtr
> triangulatedPolygons
;
60 if (decomposer
.TriangulatePolygon(pPolygon
, triangulatedPolygons
))
62 unnecessaryPolygonList
.push_back(pPolygon
);
63 for (int k
= 0, iTriangulatedPolygonCount(triangulatedPolygons
.size()); k
< iTriangulatedPolygonCount
; ++k
)
65 newPolygonList
.push_back(triangulatedPolygons
[k
]);
66 int nVertexIndexInSubTri
= -1;
67 if (!triangulatedPolygons
[k
]->HasPosition(e
.m_v
[0], &nVertexIndexInSubTri
))
69 triangulatedPolygons
[k
]->SetPos(nVertexIndexInSubTri
, e
.m_v
[1]);
71 triangulatedPolygons
[k
]->GetComputedPlane(newPlane
);
72 triangulatedPolygons
[k
]->SetPlane(newPlane
);
73 triangulatedPolygons
[k
]->ResetUVs();
80 PolygonPtr pWeldedPolygon
= pPolygon
->Clone();
81 pWeldedPolygon
->SetPos(nVertexIndex
, e
.m_v
[1]);
82 pWeldedPolygon
->Optimize();
83 weldedPolygons
.push_back(std::pair
<PolygonPtr
, PolygonPtr
>(pPolygon
, pWeldedPolygon
));
88 for (int i
= 0, iUnnecessaryCount(unnecessaryPolygonList
.size()); i
< iUnnecessaryCount
; ++i
)
89 mc
.pModel
->RemovePolygon(unnecessaryPolygonList
[i
]);
91 for (int i
= 0, iNewPolygonCount(newPolygonList
.size()); i
< iNewPolygonCount
; ++i
)
92 mc
.pModel
->AddPolygon(newPolygonList
[i
]);
94 for (int i
= 0, iWeldedPolygonCount(weldedPolygons
.size()); i
< iWeldedPolygonCount
; ++i
)
96 mc
.pModel
->RemovePolygon(weldedPolygons
[i
].first
);
97 if (weldedPolygons
[i
].second
->IsValid() && !weldedPolygons
[i
].second
->IsOpen())
98 mc
.pModel
->AddPolygon(weldedPolygons
[i
].second
);
102 void WeldTool::Enter()
104 ElementSet
* pSelected
= DesignerSession::GetInstance()->GetSelectedElements();
106 int nSelectionCount
= pSelected
->GetCount();
107 if (nSelectionCount
< 2)
109 MessageBox("Warning", "More than two vertices should be selected for using this tool.");
110 GetDesigner()->SwitchToSelectTool();
114 for (int i
= 0; i
< nSelectionCount
; ++i
)
116 if (!(*pSelected
)[i
].IsVertex())
118 MessageBox("Warning", "Only vertices must be selected for using this tool.");
119 GetDesigner()->SwitchToSelectTool();
124 CUndo
undo("Designer : Weld");
125 GetModel()->RecordUndo("Designer : Weld", GetBaseObject());
127 Element lastSelection
= (*pSelected
)[nSelectionCount
- 1];
129 for (int i
= 0; i
< nSelectionCount
- 1; ++i
)
130 Weld(GetMainContext(), (*pSelected
)[i
].GetPos(), (*pSelected
)[i
+ 1].GetPos());
136 pSelected
->Add(lastSelection
);
137 GetDesigner()->SwitchToSelectTool();
141 REGISTER_DESIGNER_TOOL_AND_COMMAND(eDesigner_Weld
, eToolGroup_Edit
, "Weld", WeldTool
,
142 weld
, "runs weld tool", "designer.weld")