# Ifc: merge overlapping openings if possible.
git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@1145 67173fc5-114c-0410-ac8e-9d2fd5bffc1fpull/5/head
parent
16b3d19f7f
commit
4080cd601c
25
Readme.md
25
Readme.md
|
@ -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!)
|
|
@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue