# Ifc: merge overlapping openings if possible.

git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@1145 67173fc5-114c-0410-ac8e-9d2fd5bffc1f
pull/5/head
aramis_acg 2012-02-03 00:50:07 +00:00
parent 16b3d19f7f
commit 4080cd601c
2 changed files with 87 additions and 28 deletions

View File

@ -1,5 +1,5 @@
Open Asset Import Library (_assimp_) Open Asset Import Library (_assimp_)
======================================================================== ========
Table of contents Table of contents
@ -14,8 +14,7 @@ Open Asset Import Library (_assimp_)
1. Overview ### 1. Overview ###
=============
Open Asset Import Library is a Open Source library designed to load various 3d file formats and convert them into a shared, in-memory format. It supports more than 30 file formats. It also supports exporting files to a few selected file formats. Open Asset Import Library is a Open Source library designed to load various 3d file formats and convert them into a shared, in-memory format. It supports more than 30 file formats. It also supports exporting files to a few selected file formats.
@ -25,8 +24,7 @@ Its short name is _assimp_, which is an unintended joke (the abbreviation is der
__Note__: this `README` refers to the file structure used by release packages, which differs in some points from the development trunk. __Note__: this `README` refers to the file structure used by release packages, which differs in some points from the development trunk.
1.1 Supported file formats #### 1.1 Supported file formats ####
-------------
The library provides importers for a lot of file formats, including: The library provides importers for a lot of file formats, including:
@ -66,8 +64,8 @@ See [the full list here](http://assimp.sourceforge.net/main_features_formats.htm
1.2 Repository structure #### 1.2 Repository structure ####
-------------
Open Asset Import Library is implemented in C++ (but provides both a C and a Open Asset Import Library is implemented in C++ (but provides both a C and a
C++ish interface). The directory structure is: C++ish interface). The directory structure is:
@ -89,15 +87,15 @@ C++ish interface). The directory structure is:
2. Build the library ### 2. Build the library ###
=============
Take a look into the `INSTALL` file. Or fire up CMake with the usual steps. Take a look into the `INSTALL` file. Or fire up CMake with the usual steps.
3. Where to get help ### 3. Where to get help ###
=============
For more information, visit [our website](http://assimp.sourceforge.net/). Or check out the `./doc`- folder, which contains the official documentation in HTML format. For more information, visit [our website](http://assimp.sourceforge.net/). Or check out the `./doc`- folder, which contains the official documentation in HTML format.
(CHMs for Windows are included in some release packages and should be located right here in the root folder). (CHMs for Windows are included in some release packages and should be located right here in the root folder).
@ -114,15 +112,14 @@ For development stuff, there is also a mailing list, _assimp-discussions_
4. License ### 4. License ###
=============
The license of the Asset Import Library is based on the modified, __3-clause BSD__-License, which is a very liberal license. An _informal_ summary is: do whatever you want, but include Assimp's license text with your product - and don't sue us if our code doesn't work. The license of the Asset Import Library is based on the modified, __3-clause BSD__-License, which is a very liberal license. An _informal_ summary is: do whatever you want, but include Assimp's license text with your product - and don't sue us if our code doesn't work.
Note that, unlike LGPLed code, you may link statically to Assimp. Note that, unlike LGPLed code, you may link statically to Assimp.
For the formal details, see the `LICENSE` file. For the formal details, see the `LICENSE` file.
------------------------------
------------------------------ ------------------------------
(This repository is a mirror of the SVN repository located [here](https://assimp.svn.sourceforge.net/svnroot/assimp). Thanks to [klickverbot](https://github.com/klickverbot) for setting this up!) (This repository is a mirror of the SVN repository located [here](https://assimp.svn.sourceforge.net/svnroot/assimp). Thanks to [klickverbot](https://github.com/klickverbot) for setting this up!)

View File

@ -64,7 +64,6 @@ namespace Assimp {
//#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>( 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 to_int64(p) (static_cast<ulong64>(static_cast<IfcFloat>((p) ) * max_ulong64 ))
#define from_int64(p) (static_cast<IfcFloat>((p)) / max_ulong64) #define from_int64(p) (static_cast<IfcFloat>((p)) / max_ulong64)
#define from_int64_f(p) (static_cast<IfcFloat>(from_int64((p))))
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool ProcessPolyloop(const IfcPolyLoop& loop, TempMesh& meshout, ConversionData& /*conv*/) bool ProcessPolyloop(const IfcPolyLoop& loop, TempMesh& meshout, ConversionData& /*conv*/)
@ -727,6 +726,13 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,const std:
poly.push_back(ClipperLib::IntPoint( to_int64(pip.x), to_int64(pip.y) )); poly.push_back(ClipperLib::IntPoint( to_int64(pip.x), to_int64(pip.y) ));
} }
/*
ClipperLib::Polygons pol_temp(1), pol_temp2(1);
pol_temp[0] = poly;
ClipperLib::OffsetPolygons(pol_temp,pol_temp2,0.0);
poly = pol_temp2[0];
*/
if (ClipperLib::Orientation(poly)) { if (ClipperLib::Orientation(poly)) {
std::reverse(poly.begin(), poly.end()); std::reverse(poly.begin(), poly.end());
} }
@ -769,8 +775,8 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,const std:
BOOST_FOREACH(ClipperLib::IntPoint& point, opening) { BOOST_FOREACH(ClipperLib::IntPoint& point, opening) {
tmpvec.push_back( minv * IfcVector3( tmpvec.push_back( minv * IfcVector3(
vmin.x + from_int64_f(point.X) * vmax.x, vmin.x + from_int64(point.X) * vmax.x,
vmin.y + from_int64_f(point.Y) * vmax.y, vmin.y + from_int64(point.Y) * vmax.y,
coord)); coord));
} }
@ -1114,6 +1120,27 @@ void InsertWindowContours(const std::vector< BoundingBox >& bbs,
} }
} }
// ------------------------------------------------------------------------------------------------
void MergeContours (const std::vector<IfcVector2>& a, const std::vector<IfcVector2>& b, ClipperLib::ExPolygons& out)
{
ClipperLib::Clipper clipper;
ClipperLib::Polygon clip;
BOOST_FOREACH(const IfcVector2& pip, a) {
clip.push_back(ClipperLib::IntPoint( to_int64(pip.x), to_int64(pip.y) ));
}
clipper.AddPolygon(clip, ClipperLib::ptSubject);
clip.clear();
BOOST_FOREACH(const IfcVector2& pip, b) {
clip.push_back(ClipperLib::IntPoint( to_int64(pip.x), to_int64(pip.y) ));
}
clipper.AddPolygon(clip, ClipperLib::ptSubject);
clipper.Execute(ClipperLib::ctUnion, out);
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool TryAddOpenings_Quadrulate(const std::vector<TempOpening>& openings,const std::vector<IfcVector3>& nors, TempMesh& curmesh) bool TryAddOpenings_Quadrulate(const std::vector<TempOpening>& openings,const std::vector<IfcVector3>& nors, TempMesh& curmesh)
{ {
@ -1188,8 +1215,7 @@ bool TryAddOpenings_Quadrulate(const std::vector<TempOpening>& openings,const st
IfcVector2 vpmin,vpmax; IfcVector2 vpmin,vpmax;
MinMaxChooser<IfcVector2>()(vpmin,vpmax); MinMaxChooser<IfcVector2>()(vpmin,vpmax);
contours.push_back(std::vector<IfcVector2>()); std::vector<IfcVector2> contour;
std::vector<IfcVector2>& contour = contours.back();
BOOST_FOREACH(const IfcVector3& x, t.profileMesh->verts) { BOOST_FOREACH(const IfcVector3& x, t.profileMesh->verts) {
const IfcVector3 v = m * x; const IfcVector3 v = m * x;
@ -1209,21 +1235,57 @@ bool TryAddOpenings_Quadrulate(const std::vector<TempOpening>& openings,const st
if (field.find(vpmin) != field.end()) { if (field.find(vpmin) != field.end()) {
IFCImporter::LogWarn("constraint failure during generation of wall openings, results may be faulty"); IFCImporter::LogWarn("constraint failure during generation of wall openings, results may be faulty");
} }
field[vpmin] = bbs.size();
const BoundingBox& bb = BoundingBox(vpmin,vpmax); BoundingBox bb = BoundingBox(vpmin,vpmax);
// see if this BB intersects any other, in which case we could not use the Quadrify() // see if this BB intersects any other, in which case we could not use the Quadrify()
// algorithm and would revert to Poly2Tri only. // algorithm and would revert to Poly2Tri only.
BOOST_FOREACH(const BoundingBox& ibb, bbs) { for (std::vector<BoundingBox>::iterator it = bbs.begin(); it != bbs.end();) {
const BoundingBox& ibb = *it;
if (ibb.first.x < bb.second.x && ibb.second.x > bb.first.x && if (ibb.first.x < bb.second.x && ibb.second.x > bb.first.x &&
ibb.first.y < bb.second.y && ibb.second.y > bb.second.x) { ibb.first.y < bb.second.y && ibb.second.y > bb.second.x) {
IFCImporter::LogWarn("cannot use quadrify algorithm to generate wall openings due to "
"bounding box overlaps, using poly2tri fallback"); // take these two contours and try to merge them. If they overlap (which
return TryAddOpenings_Poly2Tri(openings, nors, curmesh); // should not happen, but in fact happens-in-the-real-world [tm] ),
// resume using a single contour and a single bounding box.
const std::vector<IfcVector2>& other = contours[std::distance(bbs.begin(),it)];
ClipperLib::ExPolygons poly;
MergeContours(contour, other, poly);
if (poly.size() > 1) {
IFCImporter::LogWarn("cannot use quadrify algorithm to generate wall openings due to "
"bounding box overlaps, using poly2tri fallback");
return TryAddOpenings_Poly2Tri(openings, nors, curmesh);
}
else {
ai_assert(poly.size());
IFCImporter::LogDebug("merging oberlapping openings, this should not happen");
contour.clear();
BOOST_FOREACH(const ClipperLib::IntPoint& point, poly[0].outer) {
contour.push_back( IfcVector2( from_int64(point.X), from_int64(point.Y)));
}
bb.first = std::min(bb.first, ibb.first);
bb.second = std::min(bb.second, ibb.second);
contours.erase(contours.begin() + std::distance(bbs.begin(),it));
it = bbs.erase(it);
if (it == bbs.end()) {
break;
}
continue;
}
} }
++it;
} }
contours.push_back(contour);
field[bb.first] = bbs.size();
bbs.push_back(bb); bbs.push_back(bb);
} }
@ -1280,8 +1342,8 @@ bool TryAddOpenings_Quadrulate(const std::vector<TempOpening>& openings,const st
iold.push_back(ex.outer.size()); iold.push_back(ex.outer.size());
BOOST_FOREACH(const ClipperLib::IntPoint& point, ex.outer) { BOOST_FOREACH(const ClipperLib::IntPoint& point, ex.outer) {
vold.push_back( minv * IfcVector3( vold.push_back( minv * IfcVector3(
vmin.x + from_int64_f(point.X) * vmax.x, vmin.x + from_int64(point.X) * vmax.x,
vmin.y + from_int64_f(point.Y) * vmax.y, vmin.y + from_int64(point.Y) * vmax.y,
coord)); coord));
} }
} }