Fix the build

pull/5220/head
Kim Kulling 2023-09-06 13:45:17 +02:00
parent 4de723d497
commit 9834a6aa7d
2 changed files with 104 additions and 156 deletions

View File

@ -38,13 +38,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
/** @file IFCOpenings.cpp
* @brief Implements a subset of Ifc CSG operations for pouring
* holes for windows and doors into walls.
*/
/// @file IFCOpenings.cpp
/// @brief Implements a subset of Ifc CSG operations for pouring
/// holes for windows and doors into walls.
#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
#include "IFCUtil.h"
#include "Common/PolyTools.h"
#include "PostProcessing/ProcessHelper.h"
@ -53,9 +52,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# include <poly2tri/poly2tri.h>
# include <polyclipping/clipper.hpp>
#else
# include "../contrib/poly2tri/poly2tri/poly2tri.h"
# include "../contrib/clipper/clipper.hpp"
#endif
# include "contrib/poly2tri/poly2tri/poly2tri.h"
# include "contrib/clipper/clipper.hpp"
#endif // ASSIMP_USE_HUNTER
#include <deque>
#include <forward_list>
@ -63,32 +62,33 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <utility>
namespace Assimp {
namespace IFC {
namespace IFC {
using ClipperLib::ulong64;
// XXX use full -+ range ...
const ClipperLib::long64 max_ulong64 = 1518500249; // clipper.cpp / hiRange var
using ClipperLib::ulong64;
//#define to_int64(p) (static_cast<ulong64>( std::max( 0., std::min( static_cast<IfcFloat>((p)), 1.) ) * max_ulong64 ))
#define to_int64(p) (static_cast<ulong64>(static_cast<IfcFloat>((p) ) * max_ulong64 ))
#define from_int64(p) (static_cast<IfcFloat>((p)) / max_ulong64)
#define one_vec (IfcVector2(static_cast<IfcFloat>(1.0),static_cast<IfcFloat>(1.0)))
// XXX use full -+ range ...
const ClipperLib::long64 max_ulong64 = 1518500249; // clipper.cpp / hiRange var
inline ulong64 to_int64(IfcFloat p) {
return (static_cast<ulong64>(static_cast<IfcFloat>((p) ) * max_ulong64 ));
}
// fallback method to generate wall openings
bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,
TempMesh& curmesh);
inline IfcFloat from_int64(ulong64 p) {
return (static_cast<IfcFloat>((p)) / max_ulong64);
}
const IfcVector2 one_vec(IfcVector2(static_cast<IfcFloat>(1.0),static_cast<IfcFloat>(1.0)));
typedef std::pair< IfcVector2, IfcVector2 > BoundingBox;
typedef std::map<IfcVector2,size_t,XYSorter> XYSortedField;
// fallback method to generate wall openings
bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings, TempMesh& curmesh);
using BoundingBox = std::pair< IfcVector2, IfcVector2 >;
using XYSortedField = std::map<IfcVector2,size_t,XYSorter>;
// ------------------------------------------------------------------------------------------------
void QuadrifyPart(const IfcVector2& pmin, const IfcVector2& pmax, XYSortedField& field,
const std::vector< BoundingBox >& bbs,
std::vector<IfcVector2>& out)
{
const std::vector< BoundingBox >& bbs,
std::vector<IfcVector2>& out) {
if (!(pmin.x-pmax.x) || !(pmin.y-pmax.y)) {
return;
}
@ -142,19 +142,12 @@ void QuadrifyPart(const IfcVector2& pmin, const IfcVector2& pmax, XYSortedField&
}
if (bb.second.y > ylast) {
found = true;
const IfcFloat ys = std::max(bb.first.y,pmin.y), ye = std::min(bb.second.y,pmax.y);
if (ys - ylast > 0.0f) {
QuadrifyPart( IfcVector2(xs,ylast), IfcVector2(xe,ys) ,field,bbs,out);
}
// the following are the window vertices
/*wnd.push_back(IfcVector2(xs,ys));
wnd.push_back(IfcVector2(xs,ye));
wnd.push_back(IfcVector2(xe,ye));
wnd.push_back(IfcVector2(xe,ys));*/
ylast = ye;
}
}
@ -176,23 +169,17 @@ void QuadrifyPart(const IfcVector2& pmin, const IfcVector2& pmax, XYSortedField&
}
}
typedef std::vector<IfcVector2> Contour;
typedef std::vector<bool> SkipList; // should probably use int for performance reasons
using Contour = std::vector<IfcVector2>;
using SkipList = std::vector<bool>; // should probably use int for performance reasons
struct ProjectedWindowContour
{
struct ProjectedWindowContour {
Contour contour;
BoundingBox bb;
SkipList skiplist;
bool is_rectangular;
ProjectedWindowContour(const Contour& contour, const BoundingBox& bb, bool is_rectangular)
: contour(contour)
, bb(bb)
, is_rectangular(is_rectangular)
{}
ProjectedWindowContour(const Contour& contour, const BoundingBox& bb, bool is_rectangular)
: contour(contour), bb(bb) , is_rectangular(is_rectangular) {}
bool IsInvalid() const {
return contour.empty();
@ -207,19 +194,17 @@ struct ProjectedWindowContour
}
};
typedef std::vector< ProjectedWindowContour > ContourVector;
using ContourVector = std::vector<ProjectedWindowContour>;
// ------------------------------------------------------------------------------------------------
bool BoundingBoxesOverlapping( const BoundingBox &ibb, const BoundingBox &bb )
{
static bool BoundingBoxesOverlapping( const BoundingBox &ibb, const BoundingBox &bb ) {
// count the '=' case as non-overlapping but as adjacent to each other
return ibb.first.x < bb.second.x && ibb.second.x > bb.first.x &&
ibb.first.y < bb.second.y && ibb.second.y > bb.first.y;
}
// ------------------------------------------------------------------------------------------------
bool IsDuplicateVertex(const IfcVector2& vv, const std::vector<IfcVector2>& temp_contour)
{
static bool IsDuplicateVertex(const IfcVector2& vv, const std::vector<IfcVector2>& temp_contour) {
// sanity check for duplicate vertices
for(const IfcVector2& cp : temp_contour) {
if ((cp-vv).SquareLength() < 1e-5f) {
@ -230,14 +215,13 @@ bool IsDuplicateVertex(const IfcVector2& vv, const std::vector<IfcVector2>& temp
}
// ------------------------------------------------------------------------------------------------
void ExtractVerticesFromClipper(const ClipperLib::Polygon& poly, std::vector<IfcVector2>& temp_contour,
bool filter_duplicates = false)
{
void ExtractVerticesFromClipper(const ClipperLib::Path& poly, std::vector<IfcVector2>& temp_contour,
bool filter_duplicates = false) {
temp_contour.clear();
for(const ClipperLib::IntPoint& point : poly) {
IfcVector2 vv = IfcVector2( from_int64(point.X), from_int64(point.Y));
vv = std::max(vv,IfcVector2());
vv = std::min(vv,one_vec);
vv = std::max(vv, IfcVector2());
vv = std::min(vv, one_vec);
if (!filter_duplicates || !IsDuplicateVertex(vv, temp_contour)) {
temp_contour.push_back(vv);
@ -246,13 +230,12 @@ void ExtractVerticesFromClipper(const ClipperLib::Polygon& poly, std::vector<Ifc
}
// ------------------------------------------------------------------------------------------------
BoundingBox GetBoundingBox(const ClipperLib::Polygon& poly)
{
BoundingBox GetBoundingBox(const ClipperLib::Path& poly) {
IfcVector2 newbb_min, newbb_max;
MinMaxChooser<IfcVector2>()(newbb_min, newbb_max);
for(const ClipperLib::IntPoint& point : poly) {
IfcVector2 vv = IfcVector2( from_int64(point.X), from_int64(point.Y));
for (const ClipperLib::IntPoint& point : poly) {
IfcVector2 vv = IfcVector2(from_int64(point.X), from_int64(point.Y));
// sanity rounding
vv = std::max(vv,IfcVector2());
@ -265,12 +248,9 @@ BoundingBox GetBoundingBox(const ClipperLib::Polygon& poly)
}
// ------------------------------------------------------------------------------------------------
void InsertWindowContours(const ContourVector& contours,
const std::vector<TempOpening>& /*openings*/,
TempMesh& curmesh)
{
void InsertWindowContours(const ContourVector& contours, const std::vector<TempOpening>& /*openings*/, TempMesh& curmesh) {
// fix windows - we need to insert the real, polygonal shapes into the quadratic holes that we have now
for(size_t i = 0; i < contours.size();++i) {
for (size_t i = 0; i < contours.size(); ++i) {
const BoundingBox& bb = contours[i].bb;
const std::vector<IfcVector2>& contour = contours[i].contour;
if(contour.empty()) {
@ -287,8 +267,7 @@ void InsertWindowContours(const ContourVector& contours,
const std::set<IfcVector2,XYSorter>::const_iterator end = verts.end();
if (verts.find(bb.first)!=end && verts.find(bb.second)!=end
&& verts.find(IfcVector2(bb.first.x,bb.second.y))!=end
&& verts.find(IfcVector2(bb.second.x,bb.first.y))!=end
) {
&& verts.find(IfcVector2(bb.second.x,bb.first.y))!=end ) {
continue;
}
}
@ -313,8 +292,7 @@ void InsertWindowContours(const ContourVector& contours,
if (std::fabs(v.x-bb.first.x)<epsilon) {
edge.x = bb.first.x;
hit = true;
}
else if (std::fabs(v.x-bb.second.x)<epsilon) {
} else if (std::fabs(v.x-bb.second.x)<epsilon) {
edge.x = bb.second.x;
hit = true;
}
@ -322,8 +300,7 @@ void InsertWindowContours(const ContourVector& contours,
if (std::fabs(v.y-bb.first.y)<epsilon) {
edge.y = bb.first.y;
hit = true;
}
else if (std::fabs(v.y-bb.second.y)<epsilon) {
} else if (std::fabs(v.y-bb.second.y)<epsilon) {
edge.y = bb.second.y;
hit = true;
}
@ -347,26 +324,22 @@ void InsertWindowContours(const ContourVector& contours,
}
if (edge != contour[last_hit]) {
IfcVector2 corner = edge;
if (std::fabs(contour[last_hit].x-bb.first.x)<epsilon) {
corner.x = bb.first.x;
}
else if (std::fabs(contour[last_hit].x-bb.second.x)<epsilon) {
} else if (std::fabs(contour[last_hit].x-bb.second.x)<epsilon) {
corner.x = bb.second.x;
}
if (std::fabs(contour[last_hit].y-bb.first.y)<epsilon) {
corner.y = bb.first.y;
}
else if (std::fabs(contour[last_hit].y-bb.second.y)<epsilon) {
} else if (std::fabs(contour[last_hit].y-bb.second.y)<epsilon) {
corner.y = bb.second.y;
}
curmesh.mVerts.emplace_back(corner.x, corner.y, 0.0f);
}
else if (cnt == 1) {
} else if (cnt == 1) {
// avoid degenerate polygons (also known as lines or points)
curmesh.mVerts.erase(curmesh.mVerts.begin()+old,curmesh.mVerts.end());
}
@ -378,8 +351,7 @@ void InsertWindowContours(const ContourVector& contours,
if (n == very_first_hit) {
break;
}
}
else {
} else {
very_first_hit = n;
}
@ -390,14 +362,11 @@ void InsertWindowContours(const ContourVector& contours,
}
// ------------------------------------------------------------------------------------------------
void MergeWindowContours (const std::vector<IfcVector2>& a,
const std::vector<IfcVector2>& b,
ClipperLib::ExPolygons& out)
{
void MergeWindowContours (const std::vector<IfcVector2>& a, const std::vector<IfcVector2>& b, ClipperLib::Paths& out) {
out.clear();
ClipperLib::Clipper clipper;
ClipperLib::Polygon clip;
ClipperLib::Path clip;
for(const IfcVector2& pip : a) {
clip.emplace_back(to_int64(pip.x), to_int64(pip.y));
@ -407,7 +376,7 @@ void MergeWindowContours (const std::vector<IfcVector2>& a,
std::reverse(clip.begin(), clip.end());
}
clipper.AddPolygon(clip, ClipperLib::ptSubject);
clipper.AddPath(clip, ClipperLib::ptSubject, true);
clip.clear();
for(const IfcVector2& pip : b) {
@ -418,7 +387,7 @@ void MergeWindowContours (const std::vector<IfcVector2>& a,
std::reverse(clip.begin(), clip.end());
}
clipper.AddPolygon(clip, ClipperLib::ptSubject);
clipper.AddPath(clip, ClipperLib::ptSubject, true);
clipper.Execute(ClipperLib::ctUnion, out,ClipperLib::pftNonZero,ClipperLib::pftNonZero);
}
@ -426,12 +395,12 @@ void MergeWindowContours (const std::vector<IfcVector2>& a,
// Subtract a from b
void MakeDisjunctWindowContours (const std::vector<IfcVector2>& a,
const std::vector<IfcVector2>& b,
ClipperLib::ExPolygons& out)
ClipperLib::Paths& out)
{
out.clear();
ClipperLib::Clipper clipper;
ClipperLib::Polygon clip;
ClipperLib::Path clip;
for(const IfcVector2& pip : a) {
clip.emplace_back(to_int64(pip.x), to_int64(pip.y));
@ -441,7 +410,7 @@ void MakeDisjunctWindowContours (const std::vector<IfcVector2>& a,
std::reverse(clip.begin(), clip.end());
}
clipper.AddPolygon(clip, ClipperLib::ptClip);
clipper.AddPath(clip, ClipperLib::ptClip, true);
clip.clear();
for(const IfcVector2& pip : b) {
@ -452,30 +421,28 @@ void MakeDisjunctWindowContours (const std::vector<IfcVector2>& a,
std::reverse(clip.begin(), clip.end());
}
clipper.AddPolygon(clip, ClipperLib::ptSubject);
clipper.AddPath(clip, ClipperLib::ptSubject, true);
clipper.Execute(ClipperLib::ctDifference, out,ClipperLib::pftNonZero,ClipperLib::pftNonZero);
}
// ------------------------------------------------------------------------------------------------
void CleanupWindowContour(ProjectedWindowContour& window)
{
void CleanupWindowContour(ProjectedWindowContour& window) {
std::vector<IfcVector2> scratch;
std::vector<IfcVector2>& contour = window.contour;
ClipperLib::Polygon subject;
ClipperLib::Path subject;
ClipperLib::Clipper clipper;
ClipperLib::ExPolygons clipped;
ClipperLib::Paths clipped;
for(const IfcVector2& pip : contour) {
subject.emplace_back(to_int64(pip.x), to_int64(pip.y));
}
clipper.AddPolygon(subject,ClipperLib::ptSubject);
clipper.AddPath(subject,ClipperLib::ptSubject, true);
clipper.Execute(ClipperLib::ctUnion,clipped,ClipperLib::pftNonZero,ClipperLib::pftNonZero);
// This should yield only one polygon or something went wrong
if (clipped.size() != 1) {
// Empty polygon? drop the contour altogether
if(clipped.empty()) {
IFCImporter::LogError("error during polygon clipping, window contour is degenerate");
@ -487,7 +454,7 @@ void CleanupWindowContour(ProjectedWindowContour& window)
IFCImporter::LogError("error during polygon clipping, window contour is not convex");
}
ExtractVerticesFromClipper(clipped[0].outer, scratch);
ExtractVerticesFromClipper(clipped[0], scratch);
// Assume the bounding box doesn't change during this operation
}
@ -499,16 +466,14 @@ void CleanupWindowContours(ContourVector& contours)
for(ProjectedWindowContour& window : contours) {
CleanupWindowContour(window);
}
}
catch (const char* sx) {
} catch (const char* sx) {
IFCImporter::LogError("error during polygon clipping, window shape may be wrong: (Clipper: "
+ std::string(sx) + ")");
}
}
// ------------------------------------------------------------------------------------------------
void CleanupOuterContour(const std::vector<IfcVector2>& contour_flat, TempMesh& curmesh)
{
void CleanupOuterContour(const std::vector<IfcVector2>& contour_flat, TempMesh& curmesh) {
std::vector<IfcVector3> vold;
std::vector<unsigned int> iold;
@ -518,11 +483,11 @@ void CleanupOuterContour(const std::vector<IfcVector2>& contour_flat, TempMesh&
// Fix the outer contour using polyclipper
try {
ClipperLib::Polygon subject;
ClipperLib::Path subject;
ClipperLib::Clipper clipper;
ClipperLib::ExPolygons clipped;
ClipperLib::Paths clipped;
ClipperLib::Polygon clip;
ClipperLib::Path clip;
clip.reserve(contour_flat.size());
for(const IfcVector2& pip : contour_flat) {
clip.emplace_back(to_int64(pip.x), to_int64(pip.y));
@ -551,18 +516,15 @@ void CleanupOuterContour(const std::vector<IfcVector2>& contour_flat, TempMesh&
std::reverse(subject.begin(), subject.end());
}
clipper.AddPolygon(subject,ClipperLib::ptSubject);
clipper.AddPolygon(clip,ClipperLib::ptClip);
clipper.AddPath(subject,ClipperLib::ptSubject, true);
clipper.AddPath(clip,ClipperLib::ptClip, true);
clipper.Execute(ClipperLib::ctIntersection,clipped,ClipperLib::pftNonZero,ClipperLib::pftNonZero);
for(const ClipperLib::ExPolygon& ex : clipped) {
iold.push_back(static_cast<unsigned int>(ex.outer.size()));
for(const ClipperLib::IntPoint& point : ex.outer) {
vold.emplace_back(
from_int64(point.X),
from_int64(point.Y),
0.0f);
for(const ClipperLib::Path& ex : clipped) {
iold.push_back(static_cast<unsigned int>(ex.size()));
for(const ClipperLib::IntPoint& point : ex) {
vold.emplace_back(from_int64(point.X), from_int64(point.Y), 0.0f);
}
}
@ -571,8 +533,7 @@ void CleanupOuterContour(const std::vector<IfcVector2>& contour_flat, TempMesh&
clipper.Clear();
}
}
}
catch (const char* sx) {
} catch (const char* sx) {
IFCImporter::LogError("Ifc: error during polygon clipping, wall contour line may be wrong: (Clipper: "
+ std::string(sx) + ")");
@ -593,8 +554,7 @@ typedef std::vector<std::pair<
> ContourRefVector;
// ------------------------------------------------------------------------------------------------
bool BoundingBoxesAdjacent(const BoundingBox& bb, const BoundingBox& ibb)
{
bool BoundingBoxesAdjacent(const BoundingBox& bb, const BoundingBox& ibb) {
// TODO: I'm pretty sure there is a much more compact way to check this
const IfcFloat epsilon = Math::getEpsilon<float>();
return (std::fabs(bb.second.x - ibb.first.x) < epsilon && bb.first.y <= ibb.second.y && bb.second.y >= ibb.first.y) ||
@ -648,8 +608,7 @@ bool IntersectingLineSegments(const IfcVector2& n0, const IfcVector2& n1,
if (std::fabs(s1) == inf && std::fabs(n0_to_m1.x) < smalle) {
s1 = 0.;
}
}
else {
} else {
s0 = n0_to_m0.y / n0_to_n1.y;
s1 = n0_to_m1.y / n0_to_n1.y;
@ -1318,7 +1277,7 @@ bool GenerateOpenings(std::vector<TempOpening>& openings,
}
const std::vector<IfcVector2>& other = (*it).contour;
ClipperLib::ExPolygons poly;
ClipperLib::Paths poly;
// First check whether subtracting the old contour (to which ibb belongs)
// from the new contour (to which bb belongs) yields an updated bb which
@ -1326,12 +1285,12 @@ bool GenerateOpenings(std::vector<TempOpening>& openings,
MakeDisjunctWindowContours(other, temp_contour, poly);
if(poly.size() == 1) {
const BoundingBox newbb = GetBoundingBox(poly[0].outer);
const BoundingBox newbb = GetBoundingBox(poly[0]);
if (!BoundingBoxesOverlapping(ibb, newbb )) {
// Good guy bounding box
bb = newbb ;
ExtractVerticesFromClipper(poly[0].outer, temp_contour, false);
ExtractVerticesFromClipper(poly[0], temp_contour, false);
continue;
}
}
@ -1343,15 +1302,13 @@ bool GenerateOpenings(std::vector<TempOpening>& openings,
if (poly.size() > 1) {
return TryAddOpenings_Poly2Tri(openings, curmesh);
}
else if (poly.size() == 0) {
} else if (poly.empty()) {
IFCImporter::LogWarn("ignoring duplicate opening");
temp_contour.clear();
break;
}
else {
} else {
IFCImporter::LogVerboseDebug("merging overlapping openings");
ExtractVerticesFromClipper(poly[0].outer, temp_contour, false);
ExtractVerticesFromClipper(poly[0], temp_contour, false);
// Generate the union of the bounding boxes
bb.first = std::min(bb.first, ibb.first);
@ -1494,7 +1451,6 @@ static void logSegment(std::pair<IfcVector2,IfcVector2> segment) {
std::vector<std::vector<IfcVector2>> GetContoursInPlane3D(const std::shared_ptr<TempMesh>& mesh,IfcMatrix3 planeSpace,
IfcFloat planeOffset) {
{
std::stringstream msg;
msg << "GetContoursInPlane3D: planeSpace is \n";
@ -1552,15 +1508,12 @@ std::vector<std::vector<IfcVector2>> GetContoursInPlane3D(const std::shared_ptr<
if(std::fabs(vn.z - planeOffset) < close) {
// on the plane
intersection = vn;
}
else if((vn.z > planeOffset) != (vp.z > planeOffset))
{
} else if((vn.z > planeOffset) != (vp.z > planeOffset)) {
// passes through the plane
auto vdir = vn - vp;
auto scale = (planeOffset - vp.z) / vdir.z;
intersection = vp + scale * vdir;
}
else {
} else {
// nowhere near - move on
continue;
}
@ -1575,15 +1528,13 @@ std::vector<std::vector<IfcVector2>> GetContoursInPlane3D(const std::shared_ptr<
logSegment(s);
lineSegments.push_back(s);
// next firstpoint should be this one
}
else {
} else {
// store the first intersection point
firstPoint.x = intersection.x;
firstPoint.y = intersection.y;
gotFirstPoint = true;
}
}
else {
} else {
// now got the second point, so store the pair
IfcVector2 secondPoint(intersection.x,intersection.y);
auto s = std::pair<IfcVector2,IfcVector2>(firstPoint,secondPoint);
@ -1771,15 +1722,13 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,
// If this happens then the projection must have been wrong.
ai_assert(vmax.Length());
ClipperLib::ExPolygons clipped;
ClipperLib::Polygons holes_union;
ClipperLib::Paths clipped;
ClipperLib::Paths holes_union;
IfcVector3 wall_extrusion;
bool first = true;
try {
ClipperLib::Clipper clipper_holes;
for(const TempOpening& t : openings) {
@ -1787,7 +1736,7 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,
for(auto& contour : contours) {
// scale to clipping space
ClipperLib::Polygon hole;
ClipperLib::Path hole;
for(IfcVector2& pip : contour) {
pip.x = (pip.x - vmin.x) / vmax.x;
pip.y = (pip.y - vmin.y) / vmax.y;
@ -1806,7 +1755,7 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,
ClipperLib::OffsetPolygons(pol_temp,pol_temp2,5.0);
hole = pol_temp2[0];*/
clipper_holes.AddPolygon(hole,ClipperLib::ptSubject);
clipper_holes.AddPath(hole,ClipperLib::ptSubject, true);
{
std::stringstream msg;
msg << "- added polygon ";
@ -1829,7 +1778,7 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,
// Now that we have the big union of all holes, subtract it from the outer contour
// to obtain the final polygon to feed into the triangulator.
{
ClipperLib::Polygon poly;
ClipperLib::Path poly;
for(IfcVector2& pip : contour_flat) {
pip.x = (pip.x - vmin.x) / vmax.x;
pip.y = (pip.y - vmin.y) / vmax.y;
@ -1841,16 +1790,15 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,
std::reverse(poly.begin(), poly.end());
}
clipper_holes.Clear();
clipper_holes.AddPolygon(poly,ClipperLib::ptSubject);
clipper_holes.AddPath(poly,ClipperLib::ptSubject, true);
clipper_holes.AddPolygons(holes_union,ClipperLib::ptClip);
clipper_holes.AddPaths(holes_union,ClipperLib::ptClip, true);
clipper_holes.Execute(ClipperLib::ctDifference,clipped,
ClipperLib::pftNonZero,
ClipperLib::pftNonZero);
}
}
catch (const char* sx) {
} catch (const char* sx) {
IFCImporter::LogError("Ifc: error during polygon clipping, skipping openings for this face: (Clipper: "
+ std::string(sx) + ")");
@ -1864,13 +1812,13 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,
old_vertcnt.swap(curmesh.mVertcnt);
std::vector< std::vector<p2t::Point*> > contours;
for(ClipperLib::ExPolygon& clip : clipped) {
for(ClipperLib::Path &clip : clipped) {
contours.clear();
// Build the outer polygon contour line for feeding into poly2tri
std::vector<p2t::Point*> contour_points;
for(ClipperLib::IntPoint& point : clip.outer) {
for(ClipperLib::IntPoint& point : clip) {
contour_points.push_back( new p2t::Point(from_int64(point.X), from_int64(point.Y)) );
}
@ -1890,7 +1838,7 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,
// Build the poly2tri inner contours for all holes we got from ClipperLib
for(ClipperLib::Polygon& opening : clip.holes) {
for(ClipperLib::Path& opening : holes_union) {
contours.emplace_back();
std::vector<p2t::Point*>& contour = contours.back();
@ -1945,12 +1893,11 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,
return result;
}
} // ! IFC
} // ! IFC
} // ! Assimp
#undef to_int64
#undef from_int64
#undef one_vec
#endif
#endif // ASSIMP_BUILD_NO_IFC_IMPORTER

View File

@ -718,7 +718,8 @@ void DisposeOutPts(OutPt*& pp)
inline void InitEdge(TEdge* e, TEdge* eNext, TEdge* ePrev, const IntPoint& Pt)
{
std::memset(e, 0, sizeof(TEdge));
*e = {};
//std::memset(e, 0, sizeof(TEdge));
e->Next = eNext;
e->Prev = ePrev;
e->Curr = Pt;
@ -4329,10 +4330,10 @@ double DistanceFromLineSqrd(
const IntPoint& pt, const IntPoint& ln1, const IntPoint& ln2)
{
//The equation of a line in general form (Ax + By + C = 0)
//given 2 points (x¹,y¹) & (x²,y²) is ...
//(y¹ - y²)x + (x² - x¹)y + (y² - y¹)x¹ - (x² - x¹)y¹ = 0
//A = (y¹ - y²); B = (x² - x¹); C = (y² - y¹)x¹ - (x² - x¹)y¹
//perpendicular distance of point (x³,y³) = (Ax³ + By³ + C)/Sqrt(A² + B²)
//given 2 points (x<EFBFBD>,y<>) & (x<>,y<>) is ...
//(y<EFBFBD> - y<>)x + (x<> - x<>)y + (y<> - y<>)x<> - (x<> - x<>)y<> = 0
//A = (y<EFBFBD> - y<>); B = (x<> - x<>); C = (y<> - y<>)x<> - (x<> - x<>)y<>
//perpendicular distance of point (x<EFBFBD>,y<>) = (Ax<41> + By<42> + C)/Sqrt(A<> + B<>)
//see http://en.wikipedia.org/wiki/Perpendicular_distance
double A = double(ln1.Y - ln2.Y);
double B = double(ln2.X - ln1.X);