MCPcopy Create free account
hub / github.com/assimp/assimp / ProcessPolygonBoundaries

Function ProcessPolygonBoundaries

code/AssetLib/IFC/IFCGeometry.cpp:84–185  ·  view source on GitHub ↗

------------------------------------------------------------------------------------------------

Source from the content-addressed store, hash-verified

82
83// ------------------------------------------------------------------------------------------------
84void ProcessPolygonBoundaries(TempMesh& result, const TempMesh& inmesh, size_t master_bounds = (size_t)-1) {
85 // handle all trivial cases
86 if(inmesh.mVertcnt.empty()) {
87 return;
88 }
89 if(inmesh.mVertcnt.size() == 1) {
90 result.Append(inmesh);
91 return;
92 }
93
94 ai_assert(std::count(inmesh.mVertcnt.begin(), inmesh.mVertcnt.end(), 0u) == 0);
95
96 typedef std::vector<unsigned int>::const_iterator face_iter;
97
98 face_iter begin = inmesh.mVertcnt.begin(), end = inmesh.mVertcnt.end(), iit;
99 std::vector<unsigned int>::const_iterator outer_polygon_it = end;
100
101 // major task here: given a list of nested polygon boundaries (one of which
102 // is the outer contour), reduce the triangulation task arising here to
103 // one that can be solved using the "quadrulation" algorithm which we use
104 // for pouring windows out of walls. The algorithm does not handle all
105 // cases but at least it is numerically stable and gives "nice" triangles.
106
107 // first compute normals for all polygons using Newell's algorithm
108 // do not normalize 'normals', we need the original length for computing the polygon area
109 std::vector<IfcVector3> normals;
110 inmesh.ComputePolygonNormals(normals,false);
111
112 // One of the polygons might be a IfcFaceOuterBound (in which case `master_bounds`
113 // is its index). Sadly we can't rely on it, the docs say 'At most one of the bounds
114 // shall be of the type IfcFaceOuterBound'
115 IfcFloat area_outer_polygon = 1e-10f;
116 if (master_bounds != (size_t)-1) {
117 ai_assert(master_bounds < inmesh.mVertcnt.size());
118 outer_polygon_it = begin + master_bounds;
119 } else {
120 for(iit = begin; iit != end; ++iit) {
121 // find the polygon with the largest area and take it as the outer bound.
122 IfcVector3& n = normals[std::distance(begin,iit)];
123 const IfcFloat area = n.SquareLength();
124 if (area > area_outer_polygon) {
125 area_outer_polygon = area;
126 outer_polygon_it = iit;
127 }
128 }
129 }
130
131 if (outer_polygon_it == end) {
132 return;
133 }
134
135 const size_t outer_polygon_size = *outer_polygon_it;
136 const IfcVector3& master_normal = normals[std::distance(begin, outer_polygon_it)];
137
138 // Generate fake openings to meet the interface for the quadrulate
139 // algorithm. It boils down to generating small boxes given the
140 // inner polygon and the surface normal of the outer contour.
141 // It is important that we use the outer contour's normal because

Callers 1

ProcessConnectedFaceSetFunction · 0.85

Calls 11

GenerateOpeningsFunction · 0.85
ComputePolygonNormalsMethod · 0.80
emplace_backMethod · 0.80
distanceFunction · 0.50
emptyMethod · 0.45
sizeMethod · 0.45
AppendMethod · 0.45
beginMethod · 0.45
endMethod · 0.45
reserveMethod · 0.45
push_backMethod · 0.45

Tested by

no test coverage detected