1#include "PolyExtrude.h"
2#include "Topology/PointSet.h"
3#include "GLSurfaceVisualModule.h"
4#include "GLWireframeVisualModule.h"
5#include "GLPointVisualModule.h"
11 template<typename TDataType>
12 PolyExtrude<TDataType>::PolyExtrude()
14 this->stateTriangleSet()->setDataPtr(std::make_shared<TriangleSet<TDataType>>());
16 auto glModule = std::make_shared<GLSurfaceVisualModule>();
17 glModule->setColor(Color(0.8f, 0.52f, 0.25f));
18 glModule->setVisible(true);
19 this->stateTriangleSet()->connect(glModule->inTriangleSet());
20 this->graphicsPipeline()->pushModule(glModule);
22 auto glModule2 = std::make_shared<GLPointVisualModule>();
23 glModule2->setColor(Color(1, 0.1, 0.1));
24 glModule2->varPointSize()->setValue(0.001);
25 this->stateTriangleSet()->connect(glModule2->inPointSet());
26 this->graphicsPipeline()->pushModule(glModule2);
29 glModule3 = std::make_shared<GLWireframeVisualModule>();
30 glModule3->setColor(Color(1, 1, 1));
31 glModule3->varLineWidth()->setValue(0.1);
32 glModule3->varForceUpdate()->setValue(true);
34 this->stateTriangleSet()->connect(glModule3->inEdgeSet());
35 this->graphicsPipeline()->pushModule(glModule3);
37 this->varDistance()->setRange(-2,2);
38 this->varDivisions()->setRange(1,50);
40 auto callback = std::make_shared<FCallBackFunc>(std::bind(&PolyExtrude<TDataType>::varChanged, this));
42 this->varDistance()->attach(callback);
43 this->varDivisions()->attach(callback);
44 this->varReverseNormal()->attach(callback);
49 template<typename TDataType>
50 void PolyExtrude<TDataType>::resetStates()
56 template<typename TDataType>
57 void PolyExtrude<TDataType>::varChanged()
59 auto triangleSet = this->stateTriangleSet()->getDataPtr();
61 std::vector<Coord> vertices;
62 std::vector<TopologyModule::Triangle> triangles;
63 extrude(vertices, triangles);
65 triangleSet->setPoints(vertices);
66 triangleSet->setTriangles(triangles);
71 triangleSet->update();
74 template<typename TDataType>
75 void PolyExtrude<TDataType>::extrude(std::vector<Vec3f>& vertices, std::vector<TopologyModule::Triangle>& triangles)
77 auto triangleSet = this->stateTriangleSet()->getDataPtr();
78 auto distance = this->varDistance()->getData();
79 auto divisions = this->varDivisions()->getData();
81 std::string primString = this->varPrimitiveId()->getData();
83 if (divisions == 0) { divisions = 1; }
84 TriangleSet<TDataType>trilist;
86 trilist.copyFrom(this->inTriangleSet()->getData());
88 DArray<TopologyModule::Triangle> d_triangle = trilist.getTriangles();
89 CArray<TopologyModule::Triangle> c_triangle;
91 if (d_triangle.size())
93 c_triangle.assign(d_triangle);
97 auto& sa = trilist.vertex2Edge();
99 auto ss = trilist.getVertex2Triangles();
101 DArray<Coord> d_point = trilist.getPoints();
102 CArray<Coord> c_point;
105 c_point.assign(d_point);
108 DArray<TopologyModule::Edge> d_edges = trilist.getEdges();
109 CArray<TopologyModule::Edge> c_edges;
112 c_edges.assign(d_edges);
115 int n_point = this->inTriangleSet()->getDataPtr()->getPoints().size();
116 int n_triangle = this->inTriangleSet()->getDataPtr()->getTriangles().size();
117 int n_edges = this->inTriangleSet()->getDataPtr()->getEdges().size();
119 CArray<uint> c_selected_primid;
120 if (this->inPrimitiveId()->isEmpty()== false)
122 auto d_selected_primid = this->inPrimitiveId()->getData();
123 c_selected_primid.assign(d_selected_primid);
128 std::vector<int> tempPrimArray;
129 if (primString.size())
131 for (size_t i = 0; i < this->selectedPrimitiveID.size(); i++)
133 tempPrimArray.push_back(this->selectedPrimitiveID[i]);
138 for (size_t i = 0; i < c_selected_primid.size(); i++)
140 tempPrimArray.push_back(c_selected_primid[i]);
142 if (tempPrimArray.empty())
144 printf("selected empty \n");
149 std::vector<int> selectedPtNum;
151 for (int i = 0; i < tempPrimArray.size(); i++)
153 for (int j = 0; j < 3; j++)
155 for (int ptN = 0; ptN < selectedPtNum.size(); ptN++)
157 if (std::find(selectedPtNum.begin(), selectedPtNum.end(), c_triangle[i][ptN]) == selectedPtNum.end())
162 selectedPtNum.push_back(c_triangle[i][ptN]);
168 for (int i = 0; i < n_point; i++)
170 vertices.push_back(c_point[i]);
173 for (int i = 0; i < n_triangle; i++)
175 triangles.push_back(c_triangle[i]);
178 std::vector<int> tempid;
179 std::map<int, int> ptid_count;
180 std::map<int, int> ptid_allTri;
182 for (int i = 0; i < tempPrimArray.size(); i++)
184 int n = tempPrimArray[i];
187 std::vector<int> idArray = { c_triangle[n][0] ,c_triangle[n][1] ,c_triangle[n][2] };
189 for (int i = 0; i < idArray.size(); i++)
192 if (ptid_count.count(Tid))
194 ptid_count[Tid] = ptid_count.at(Tid) + 1;
204 for (int i = 0; i < n_triangle; i++)
207 std::vector<int> idArray = { c_triangle[i][0] ,c_triangle[i][1] ,c_triangle[i][2] };
209 for (int k = 0; k < idArray.size(); k++)
212 if (ptid_count.count(Tid))
214 if (ptid_allTri.count(Tid))
216 ptid_allTri[Tid] = ptid_allTri.at(Tid) + 1;
220 ptid_allTri[Tid] = 1;
228 std::vector<int> replace_id;
229 std::vector<int> border_id;
230 std::vector<int> select_ptid;
232 for (auto it : ptid_count)
234 select_ptid.push_back(it.first);
236 if (it.second == ptid_allTri.at(it.first))
238 replace_id.push_back(it.first);
242 border_id.push_back(it.first);
248 auto d_normal = this->inTriangleSet()->getDataPtr()->getVertexNormals();
250 std::map<int, Coord> map_vertexID_tNormal;
254 CArray<Coord> c_normal;
255 c_normal.assign(d_normal);
256 for (size_t i = 0; i < c_normal.size(); i++)
258 map_vertexID_tNormal[i] = c_normal[i];
261 std::vector<TopologyModule::Edge> normalDisplay;
262 std::vector<Coord> normalCoord;
263 float normalsize = 0.1f;
264 for (size_t i = 0; i < c_point.size(); i++)
266 normalCoord.push_back(c_point[i]);
267 Vec3f N = c_normal[i];
268 Vec3f P = Coord(c_point[i][0], c_point[i][1], c_point[i][2]);
269 Vec3f nP = P + N * normalsize;
270 normalCoord.push_back(Coord(nP[0],nP[1],nP[2]));
271 normalDisplay.push_back(TopologyModule::Edge(normalCoord.size(), normalCoord.size()-1));
275 std::map<point_layer, int> oriP_newP;
277 for (size_t i = 0; i < border_id.size(); i++)
279 oriP_newP[point_layer(border_id[i], 0)] = border_id[i];
283 for (size_t k = 1; k < divisions; k++)
285 float tempdistance = float(k) /divisions * distance;
287 for (int i = 0; i < border_id.size(); i++)
291 Coord pt = vertices[border_id[i]];
292 Coord N = map_vertexID_tNormal.at(border_id[i]);
294 point_layer lp = point_layer(border_id[i], k);
296 vertices.push_back(Coord(pt[0] + N[0] * tempdistance, pt[1] + N[1] * tempdistance, pt[2] + N[2] * tempdistance));
298 oriP_newP[lp] = vertices.size() - 1;
299 temp = vertices.size() - 1;
304 for (int i = 0; i < select_ptid.size(); i++)
308 Coord pt = vertices[select_ptid[i]];
309 Coord N = map_vertexID_tNormal.at(select_ptid[i]);
311 point_layer lp = point_layer(select_ptid[i], divisions);
313 if (i < border_id.size())
315 vertices.push_back(Coord(pt[0] + N[0] * distance, pt[1] + N[1] * distance, pt[2] + N[2] * distance));
317 oriP_newP[lp] = vertices.size() - 1;
318 temp = vertices.size() - 1;
323 int tempi = i - border_id.size();
324 vertices[replace_id[tempi]] = Coord(pt[0] + N[0] * distance, pt[1] + N[1] * distance, pt[2] + N[2] * distance);
326 oriP_newP[lp] = replace_id[tempi];
327 temp = replace_id[tempi];
336 std::map<int, int> borderP_countInLine;
337 std::vector<TopologyModule::Edge> borderLine;
339 for (int i = 0; i < tempPrimArray.size(); i++)
341 bool one = std::count(border_id.begin(), border_id.end(), triangles[tempPrimArray[i]][0]);
342 bool two = std::count(border_id.begin(), border_id.end(), triangles[tempPrimArray[i]][1]);
343 bool three = std::count(border_id.begin(), border_id.end(), triangles[tempPrimArray[i]][2]);
347 borderLine.push_back(TopologyModule::Edge(triangles[tempPrimArray[i]][0], triangles[tempPrimArray[i]][1]));
351 borderLine.push_back(TopologyModule::Edge(triangles[tempPrimArray[i]][1], triangles[tempPrimArray[i]][2]));
355 borderLine.push_back(TopologyModule::Edge(triangles[tempPrimArray[i]][2], triangles[tempPrimArray[i]][0]));
360 std::vector<TopologyModule::Edge> tempLine = borderLine;
361 for (size_t i = 0; i < tempLine.size(); i++)
363 int k = tempLine.size() - i - 1;
364 int row1_1 = tempLine[k][0];
365 int row1_2 = tempLine[k][1];
366 for (size_t j = 0; j < tempLine.size(); j++)
368 int row2_1 = tempLine[j][0];
369 int row2_2 = tempLine[j][1];
370 if (row1_1 == row2_2 && row1_2 == row2_1)
372 borderLine.erase(borderLine.begin() + k);
377 for (int i = 0; i < tempPrimArray.size(); i++)
379 triangles[tempPrimArray[i]][0] = oriP_newP.at(point_layer(triangles[tempPrimArray[i]][0],divisions));
380 triangles[tempPrimArray[i]][1] = oriP_newP.at(point_layer(triangles[tempPrimArray[i]][1],divisions));
381 triangles[tempPrimArray[i]][2] = oriP_newP.at(point_layer(triangles[tempPrimArray[i]][2],divisions));
384 for (size_t k = 0; k < divisions; k++)
386 for (size_t i = 0; i < borderLine.size(); i++)
388 point_layer pt_o1 = point_layer(borderLine[i][0],k);
389 point_layer pt_o2 = point_layer(borderLine[i][1],k);
391 point_layer pt_n1 = point_layer(borderLine[i][0],k + 1);
392 point_layer pt_n2 = point_layer(borderLine[i][1],k + 1);
394 triangles.push_back(TopologyModule::Triangle(oriP_newP.at(pt_o1), oriP_newP.at(pt_o2), oriP_newP.at(pt_n2)));
395 triangles.push_back(TopologyModule::Triangle(oriP_newP.at(pt_o1), oriP_newP.at(pt_n2), oriP_newP.at(pt_n1)));
404 template<typename TDataType>
405 void PolyExtrude<TDataType>::substrFromTwoString(std::string& first, std::string& Second, std::string& line, std::string& myStr, int& index)
407 if (index < int(line.size()))
409 size_t posStart = line.find(first, index);
410 size_t posEnd = line.find(Second, posStart + 1);
413 myStr = line.substr(posStart, posEnd - posStart);
416 std::stringstream ss2(line);
427 DEFINE_CLASS(PolyExtrude);