Fix missing includes.
authorKim Kulling <kim.kulling@googlemail.com>
Sun, 5 Mar 2017 14:05:40 +0000 (15:05 +0100)
committerKim Kulling <kim.kulling@googlemail.com>
Sun, 5 Mar 2017 14:05:40 +0000 (15:05 +0100)
14 files changed:
CREDITS
LICENSE
Readme.md
code/BlenderScene.cpp
code/FBXCompileConfig.h
code/FBXDocument.cpp
code/FBXParser.cpp
code/FBXProperties.h
code/FBXTokenizer.h
code/FBXUtil.cpp
code/res/assimp.rc
contrib/poly2tri/poly2tri/sweep/cdt.cc
contrib/poly2tri/poly2tri/sweep/sweep.cc
test/models/OBJ/spider.obj

diff --git a/CREDITS b/CREDITS
index 1cfe4f6..744173c 100644 (file)
--- a/CREDITS
+++ b/CREDITS
-===============================================================\r
-Open Asset Import Library (Assimp)\r
-Developers and Contributors\r
-===============================================================\r
-\r
-The following is a non-exhaustive list of all constributors over the years.\r
-If you think your name should be listed here, drop us a line and we'll add you.\r
-\r
-- Alexander Gessler,\r
-3DS-, BLEND-, ASE-, DXF-, HMP-, MDL-, MD2-, MD3-, MD5-, MDC-, NFF-, PLY-, STL-, RAW-, OFF-, MS3D-, Q3D- and LWO-Loader, Assimp-Viewer, assimp-cmd, -noboost, Website (Design).\r
-\r
-- Thomas Schulze,\r
-X-, Collada-, BVH-Loader, Postprocessing framework. Data structure & Interface design, documentation.\r
-\r
-- Kim Kulling,\r
-Obj-, Q3BSD-, OpenGEX-Loader, Logging system, CMake-build-environment, Linux-build, Website ( Admin ), Coverity ( Admin ), Glitter ( Admin ).\r
-\r
-- R.Schmidt,\r
-Linux build, eclipse support.\r
-\r
-- Matthias Gubisch,\r
-Assimp.net\r
-Visual Studio 9 support, bugfixes.\r
-\r
-- Mark Sibly\r
-B3D-Loader, Assimp testing\r
-\r
-- Jonathan Klein\r
-Ogre Loader, VC2010 fixes and CMake fixes.\r
-\r
-- Sebastian Hempel,\r
-PyAssimp (first version)\r
-Compile-Bugfixes for mingw, add environment for static library support in make.\r
-\r
-- Jonathan Pokrass\r
-Supplied a bugfix concerning the scaling in the md3 loader.\r
-\r
-- Andrew Galante,\r
-Submitted patches to make Assimp compile with GCC-4, a makefile and the xcode3 workspace.\r
-\r
-- Andreas Nagel\r
-First Assimp testing & verification under Windows Vista 64 Bit.\r
-\r
-- Marius Schr�der\r
-Allowed us to use many of his models for screenshots and testing.\r
-\r
-- Christian Schubert\r
-Supplied various XFiles for testing purposes.\r
-\r
-- Tizian Wieland\r
-Searched the web for hundreds of test models for internal use\r
-\r
-- John Connors\r
-Supplied patches for linux and SCons.\r
-\r
-- T. R.\r
-The GUY who performed some of the CSM mocaps.\r
-\r
-- Andy Maloney\r
-Contributed fixes for the documentation and the doxygen markup\r
-\r
-- Zhao Lei\r
-Contributed several bugfixes fixing memory leaks and improving float parsing \r
-\r
-- sueastside\r
-Updated PyAssimp to the latest Assimp data structures and provided a script to keep the Python binding up-to-date.\r
-\r
-- Tobias Rittig\r
-Collada testing with Cinema 4D\r
-\r
-- Brad Grantham\r
-Improvements in OpenGL-Sample.\r
-\r
-- Robert Ramirez\r
-Add group loading feature to Obj-Loader.\r
-\r
-- Chris Maiwald\r
-Many bugreports, improving Assimp's portability, regular testing & feedback.\r
-\r
-- Stepan Hrbek\r
-Bugreport and fix for a obj-materialloader crash.\r
-\r
-- David Nadlinger\r
-D bindings, CMake install support. \r
-\r
-- Dario Accornero\r
-Contributed several patches regarding Mac OS/XCode targets, bug reports.\r
-\r
-- Martin Walser (Samhayne)\r
-Contributed the 'SimpleTexturedOpenGl' sample.\r
-\r
-- Matthias Fauconneau\r
-Contributed a fix for the Q3-BSP loader.\r
-\r
-- J�rgen P. Tjern�\r
-Contributed updated and improved xcode workspaces\r
-\r
-- drparallax\r
-Contributed the /samples/SimpleAssimpViewX sample\r
-\r
-- Carsten Fuchs\r
-Contributed a fix for the Normalize method in aiQuaternion.\r
-\r
-- dbburgess\r
-Contributes a Android-specific build issue: log the hardware architecture for ARM.\r
-\r
-- alfiereinre7\r
-Contributes a obj-fileparser fix: missing tokens in the obj-token list.\r
-\r
-- Roman Kharitonov\r
-Contributes a fix for the configure script environment.\r
-\r
-- Ed Diana\r
-Contributed AssimpDelphi (/port/AssimpDelphi).\r
-\r
-- rdb \r
-Contributes a bundle of fixes and improvements for the bsp-importer.\r
-\r
-- Mick P\r
-For contributing the De-bone postprocessing step and filing various bug reports.\r
-\r
-- Rosen Diankov\r
-Contributed patches to build assimp debian packages using cmake.\r
-\r
-- Mark Page\r
-Contributed a patch to fix the VertexTriangleAdjacency postprocessing step.\r
-\r
-- IOhannes\r
-Contributed the Debian build fixes ( architecture macro ).\r
-\r
-- gellule\r
-Several LWO and LWS fixes (pivoting). \r
-\r
-- Marcel Metz\r
-GCC/Linux fixes for the SimpleOpenGL sample.\r
-\r
-- Brian Miller\r
-Bugfix for a compiler fix for iOS on arm.\r
-\r
-- S�verin Lemaignan\r
-Rewrite of PyAssimp, distutils and Python3 support\r
-\r
-- albert-wang\r
-Bugfixes for the collada parser\r
-\r
-- Ya ping Jin\r
-Bugfixes for uv-tanget calculation.\r
-\r
-- Jonne Nauha\r
-Ogre Binary format support\r
-\r
-- Filip Wasil, Tieto Poland Sp. z o.o.\r
-Android JNI asset extraction support\r
-\r
-- Richard Steffen\r
-Contributed ExportProperties interface\r
-Contributed X File exporter\r
-Contributed Step (stp) exporter\r
-\r
-\r
+===============================================================
+Open Asset Import Library (Assimp)
+Developers and Contributors
+===============================================================
+
+The following is a non-exhaustive list of all constributors over the years.
+If you think your name should be listed here, drop us a line and we'll add you.
+
+- Alexander Gessler,
+3DS-, BLEND-, ASE-, DXF-, HMP-, MDL-, MD2-, MD3-, MD5-, MDC-, NFF-, PLY-, STL-, RAW-, OFF-, MS3D-, Q3D- and LWO-Loader, Assimp-Viewer, assimp-cmd, -noboost, Website (Design).
+
+- Thomas Schulze,
+X-, Collada-, BVH-Loader, Postprocessing framework. Data structure & Interface design, documentation.
+
+- Kim Kulling,
+Obj-, Q3BSD-, OpenGEX-Loader, Logging system, CMake-build-environment, Linux-build, Website ( Admin ), Coverity ( Admin ), Glitter ( Admin ).
+
+- R.Schmidt,
+Linux build, eclipse support.
+
+- Matthias Gubisch,
+Assimp.net
+Visual Studio 9 support, bugfixes.
+
+- Mark Sibly
+B3D-Loader, Assimp testing
+
+- Jonathan Klein
+Ogre Loader, VC2010 fixes and CMake fixes.
+
+- Sebastian Hempel,
+PyAssimp (first version)
+Compile-Bugfixes for mingw, add environment for static library support in make.
+
+- Jonathan Pokrass
+Supplied a bugfix concerning the scaling in the md3 loader.
+
+- Andrew Galante,
+Submitted patches to make Assimp compile with GCC-4, a makefile and the xcode3 workspace.
+
+- Andreas Nagel
+First Assimp testing & verification under Windows Vista 64 Bit.
+
+- Marius Schr�der
+Allowed us to use many of his models for screenshots and testing.
+
+- Christian Schubert
+Supplied various XFiles for testing purposes.
+
+- Tizian Wieland
+Searched the web for hundreds of test models for internal use
+
+- John Connors
+Supplied patches for linux and SCons.
+
+- T. R.
+The GUY who performed some of the CSM mocaps.
+
+- Andy Maloney
+Contributed fixes for the documentation and the doxygen markup
+
+- Zhao Lei
+Contributed several bugfixes fixing memory leaks and improving float parsing 
+
+- sueastside
+Updated PyAssimp to the latest Assimp data structures and provided a script to keep the Python binding up-to-date.
+
+- Tobias Rittig
+Collada testing with Cinema 4D
+
+- Brad Grantham
+Improvements in OpenGL-Sample.
+
+- Robert Ramirez
+Add group loading feature to Obj-Loader.
+
+- Chris Maiwald
+Many bugreports, improving Assimp's portability, regular testing & feedback.
+
+- Stepan Hrbek
+Bugreport and fix for a obj-materialloader crash.
+
+- David Nadlinger
+D bindings, CMake install support. 
+
+- Dario Accornero
+Contributed several patches regarding Mac OS/XCode targets, bug reports.
+
+- Martin Walser (Samhayne)
+Contributed the 'SimpleTexturedOpenGl' sample.
+
+- Matthias Fauconneau
+Contributed a fix for the Q3-BSP loader.
+
+- J�rgen P. Tjern�
+Contributed updated and improved xcode workspaces
+
+- drparallax
+Contributed the /samples/SimpleAssimpViewX sample
+
+- Carsten Fuchs
+Contributed a fix for the Normalize method in aiQuaternion.
+
+- dbburgess
+Contributes a Android-specific build issue: log the hardware architecture for ARM.
+
+- alfiereinre7
+Contributes a obj-fileparser fix: missing tokens in the obj-token list.
+
+- Roman Kharitonov
+Contributes a fix for the configure script environment.
+
+- Ed Diana
+Contributed AssimpDelphi (/port/AssimpDelphi).
+
+- rdb 
+Contributes a bundle of fixes and improvements for the bsp-importer.
+
+- Mick P
+For contributing the De-bone postprocessing step and filing various bug reports.
+
+- Rosen Diankov
+Contributed patches to build assimp debian packages using cmake.
+
+- Mark Page
+Contributed a patch to fix the VertexTriangleAdjacency postprocessing step.
+
+- IOhannes
+Contributed the Debian build fixes ( architecture macro ).
+
+- gellule
+Several LWO and LWS fixes (pivoting). 
+
+- Marcel Metz
+GCC/Linux fixes for the SimpleOpenGL sample.
+
+- Brian Miller
+Bugfix for a compiler fix for iOS on arm.
+
+- S�verin Lemaignan
+Rewrite of PyAssimp, distutils and Python3 support
+
+- albert-wang
+Bugfixes for the collada parser
+
+- Ya ping Jin
+Bugfixes for uv-tanget calculation.
+
+- Jonne Nauha
+Ogre Binary format support
+
+- Filip Wasil, Tieto Poland Sp. z o.o.
+Android JNI asset extraction support
+
+- Richard Steffen
+Contributed ExportProperties interface
+Contributed X File exporter
+Contributed Step (stp) exporter
+
+
diff --git a/LICENSE b/LICENSE
index c8e47b3..262606a 100644 (file)
--- a/LICENSE
+++ b/LICENSE
@@ -1,78 +1,78 @@
-Open Asset Import Library (assimp)\r
-\r
-Copyright (c) 2006-2016, assimp team\r
-All rights reserved.\r
-\r
-Redistribution and use of this software in source and binary forms,\r
-with or without modification, are permitted provided that the\r
-following conditions are met:\r
-\r
-* Redistributions of source code must retain the above\r
-  copyright notice, this list of conditions and the\r
-  following disclaimer.\r
-\r
-* Redistributions in binary form must reproduce the above\r
-  copyright notice, this list of conditions and the\r
-  following disclaimer in the documentation and/or other\r
-  materials provided with the distribution.\r
-\r
-* Neither the name of the assimp team, nor the names of its\r
-  contributors may be used to endorse or promote products\r
-  derived from this software without specific prior\r
-  written permission of the assimp team.\r
-\r
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
-\r
-\r
-\r
-******************************************************************************\r
-\r
-AN EXCEPTION applies to all files in the ./test/models-nonbsd folder.\r
-These are 3d models for testing purposes, from various free sources\r
-on the internet. They are - unless otherwise stated - copyright of\r
-their respective creators, which may impose additional requirements\r
-on the use of their work. For any of these models, see\r
-<model-name>.source.txt for more legal information. Contact us if you\r
-are a copyright holder and believe that we credited you inproperly or\r
-if you don't want your files to appear in the repository.\r
-\r
-\r
-******************************************************************************\r
-\r
-Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors\r
-http://code.google.com/p/poly2tri/\r
-\r
-All rights reserved.\r
-Redistribution and use in source and binary forms, with or without modification,\r
-are permitted provided that the following conditions are met:\r
-\r
-* Redistributions of source code must retain the above copyright notice,\r
-  this list of conditions and the following disclaimer.\r
-* Redistributions in binary form must reproduce the above copyright notice,\r
-  this list of conditions and the following disclaimer in the documentation\r
-  and/or other materials provided with the distribution.\r
-* Neither the name of Poly2Tri nor the names of its contributors may be\r
-  used to endorse or promote products derived from this software without specific\r
-  prior written permission.\r
-\r
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\r
-CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\r
-PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\r
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+Open Asset Import Library (assimp)
+
+Copyright (c) 2006-2016, assimp team
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the
+following conditions are met:
+
+* Redistributions of source code must retain the above
+  copyright notice, this list of conditions and the
+  following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+  copyright notice, this list of conditions and the
+  following disclaimer in the documentation and/or other
+  materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+  contributors may be used to endorse or promote products
+  derived from this software without specific prior
+  written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+
+******************************************************************************
+
+AN EXCEPTION applies to all files in the ./test/models-nonbsd folder.
+These are 3d models for testing purposes, from various free sources
+on the internet. They are - unless otherwise stated - copyright of
+their respective creators, which may impose additional requirements
+on the use of their work. For any of these models, see
+<model-name>.source.txt for more legal information. Contact us if you
+are a copyright holder and believe that we credited you inproperly or
+if you don't want your files to appear in the repository.
+
+
+******************************************************************************
+
+Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
+http://code.google.com/p/poly2tri/
+
+All rights reserved.
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+  this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright notice,
+  this list of conditions and the following disclaimer in the documentation
+  and/or other materials provided with the distribution.
+* Neither the name of Poly2Tri nor the names of its contributors may be
+  used to endorse or promote products derived from this software without specific
+  prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
index 6b33168..af8225b 100644 (file)
--- a/Readme.md
+++ b/Readme.md
-Open Asset Import Library (assimp)\r
-==================================\r
-\r
-[![Linux Build Status](https://travis-ci.org/assimp/assimp.svg)](https://travis-ci.org/assimp/assimp)\r
-[![Windows Build Status](https://ci.appveyor.com/api/projects/status/tmo433wax6u6cjp4?svg=true)](https://ci.appveyor.com/project/kimkulling/assimp)\r
-<a href="https://scan.coverity.com/projects/5607">\r
-  <img alt="Coverity Scan Build Status"\r
-       src="https://scan.coverity.com/projects/5607/badge.svg"/>\r
-</a>\r
-[![Coverage Status](https://coveralls.io/repos/github/assimp/assimp/badge.svg?branch=master)](https://coveralls.io/github/assimp/assimp?branch=master)\r
-<br>\r
-\r
-APIs are provided for C and C++. There are various bindings to other languages (C#, Java, Python, Delphi, D). Assimp also runs on Android and iOS.\r
-\r
-Additionally, assimp features various __mesh post processing tools__: normals and tangent space generation, triangulation, vertex cache locality optimization, removal of degenerate primitives and duplicate vertices, sorting by primitive type, merging of redundant materials and many more.\r
-\r
-This is the development trunk containing the latest features and bugfixes. For productive use though, we recommend one of the stable releases available from [assimp.sf.net](http://assimp.sf.net) or from *nix package repositories.\r
-The current build status is:\r
-\r
-Gitter chat: [![Join the chat at https://gitter.im/assimp/assimp](https://badges.gitter.im/assimp/assimp.svg)](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)<br>\r
-__[open3mod](https://github.com/acgessler/open3mod) is a powerful 3D model viewer based on Assimp's import and export abilities.__\r
-\r
-Please check our Wiki as well: https://github.com/assimp/assimp/wiki\r
-\r
-#### Supported file formats ####\r
-\r
-A full list [is here](http://assimp.org/main_features_formats.html).\r
-__Importers__:\r
-\r
-- 3DS\r
-- BLEND (Blender)\r
-- DAE/Collada\r
-- FBX\r
-- IFC-STEP\r
-- ASE\r
-- DXF\r
-- HMP\r
-- MD2\r
-- MD3\r
-- MD5\r
-- MDC\r
-- MDL\r
-- NFF\r
-- PLY\r
-- STL\r
-- X\r
-- OBJ\r
-- OpenGEX\r
-- SMD\r
-- LWO\r
-- LXO\r
-- LWS  \r
-- TER\r
-- AC3D\r
-- MS3D\r
-- COB\r
-- Q3BSP\r
-- XGL\r
-- CSM\r
-- BVH\r
-- B3D\r
-- NDO\r
-- Ogre Binary\r
-- Ogre XML\r
-- Q3D\r
-- ASSBIN (Assimp custom format)\r
-- glTF (partial)\r
-- 3MF\r
-\r
-Additionally, some formats are supported by dependency on non-free code or external SDKs (not built by default):\r
-\r
-- C4D (https://github.com/acgessler/assimp-cinema4d)\r
-\r
-__Exporters__:\r
-\r
-- DAE (Collada)\r
-- STL\r
-- OBJ\r
-- PLY\r
-- X\r
-- 3DS\r
-- JSON (for WebGl, via https://github.com/acgessler/assimp2json)\r
-- ASSBIN\r
-- STEP\r
-- glTF (partial)\r
-\r
-### Building ###\r
-Take a look into the `INSTALL` file. Our build system is CMake, if you used CMake before there is a good chance you know what to do.\r
-\r
-### Ports ###\r
-* [Android](port/AndroidJNI/README.md)\r
-* [Python](port/PyAssimp/README.md)\r
-* [.NET](port/AssimpNET/Readme.md)\r
-* [Pascal](port/AssimpPascal/Readme.md)\r
-* [Javascript (Alpha)](https://github.com/makc/assimp2json)\r
-\r
-#### Repository structure ####\r
-Open Asset Import Library is implemented in C++. The directory structure is:\r
-\r
-       /code           Source code\r
-       /contrib        Third-party libraries\r
-       /doc            Documentation (doxysource and pre-compiled docs)\r
-       /include        Public header C and C++ header files\r
-       /scripts        Scripts used to generate the loading code for some formats\r
-       /port           Ports to other languages and scripts to maintain those.\r
-       /test           Unit- and regression tests, test suite of models\r
-       /tools          Tools (old assimp viewer, command line `assimp`)\r
-       /samples        A small number of samples to illustrate possible\r
-                        use cases for Assimp\r
-       /workspaces     Build environments for vc,xcode,... (deprecated,\r
-                       CMake has superseeded all legacy build options!)\r
-\r
-\r
-### Where to get help ###\r
-For more information, visit [our website](http://assimp.org/). Or check out the `./doc`- folder, which contains the official documentation in HTML format.\r
-(CHMs for Windows are included in some release packages and should be located right here in the root folder).\r
-\r
-If the docs don't solve your problem, ask on [StackOverflow](http://stackoverflow.com/questions/tagged/assimp?sort=newest). If you think you found a bug, please open an issue on Github.\r
-\r
-For development discussions, there is also a (very low-volume) mailing list, _assimp-discussions_\r
-  [(subscribe here)]( https://lists.sourceforge.net/lists/listinfo/assimp-discussions)\r
-\r
-Open Asset Import Library is a library to load various 3d file formats into a shared, in-memory format. It supports more than __40 file formats__ for import and a growing selection of file formats for export.\r
-\r
-And we also have a Gitter-channel:Gitter [![Join the chat at https://gitter.im/assimp/assimp](https://badges.gitter.im/assimp/assimp.svg)](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)<br>\r
-\r
-### Contributing ###\r
-Contributions to assimp are highly appreciated. The easiest way to get involved is to submit\r
-a pull request with your changes against the main repository's `master` branch.\r
-\r
-### Donate ###\r
-If you like assimp, consider buying us a beer (or two):\r
-[Donate](http://sourceforge.net/donate/index.php?group_id=226462)\r
-\r
-### License ###\r
-Our license is based on the modified, __3-clause BSD__-License.\r
-\r
-An _informal_ summary is: do whatever you want, but include Assimp's license text with your product -\r
-and don't sue us if our code doesn't work. Note that, unlike LGPLed code, you may link statically to Assimp.\r
-For the legal details, see the `LICENSE` file.\r
-\r
-### Why this name ###\r
-Sorry, we're germans :-), no english native speakers ...\r
+Open Asset Import Library (assimp)
+==================================
+
+[![Linux Build Status](https://travis-ci.org/assimp/assimp.svg)](https://travis-ci.org/assimp/assimp)
+[![Windows Build Status](https://ci.appveyor.com/api/projects/status/tmo433wax6u6cjp4?svg=true)](https://ci.appveyor.com/project/kimkulling/assimp)
+<a href="https://scan.coverity.com/projects/5607">
+  <img alt="Coverity Scan Build Status"
+       src="https://scan.coverity.com/projects/5607/badge.svg"/>
+</a>
+[![Coverage Status](https://coveralls.io/repos/github/assimp/assimp/badge.svg?branch=master)](https://coveralls.io/github/assimp/assimp?branch=master)
+<br>
+
+APIs are provided for C and C++. There are various bindings to other languages (C#, Java, Python, Delphi, D). Assimp also runs on Android and iOS.
+
+Additionally, assimp features various __mesh post processing tools__: normals and tangent space generation, triangulation, vertex cache locality optimization, removal of degenerate primitives and duplicate vertices, sorting by primitive type, merging of redundant materials and many more.
+
+This is the development trunk containing the latest features and bugfixes. For productive use though, we recommend one of the stable releases available from [assimp.sf.net](http://assimp.sf.net) or from *nix package repositories.
+The current build status is:
+
+Gitter chat: [![Join the chat at https://gitter.im/assimp/assimp](https://badges.gitter.im/assimp/assimp.svg)](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)<br>
+__[open3mod](https://github.com/acgessler/open3mod) is a powerful 3D model viewer based on Assimp's import and export abilities.__
+
+Please check our Wiki as well: https://github.com/assimp/assimp/wiki
+
+#### Supported file formats ####
+
+A full list [is here](http://assimp.org/main_features_formats.html).
+__Importers__:
+
+- 3DS
+- BLEND (Blender)
+- DAE/Collada
+- FBX
+- IFC-STEP
+- ASE
+- DXF
+- HMP
+- MD2
+- MD3
+- MD5
+- MDC
+- MDL
+- NFF
+- PLY
+- STL
+- X
+- OBJ
+- OpenGEX
+- SMD
+- LWO
+- LXO
+- LWS  
+- TER
+- AC3D
+- MS3D
+- COB
+- Q3BSP
+- XGL
+- CSM
+- BVH
+- B3D
+- NDO
+- Ogre Binary
+- Ogre XML
+- Q3D
+- ASSBIN (Assimp custom format)
+- glTF (partial)
+- 3MF
+
+Additionally, some formats are supported by dependency on non-free code or external SDKs (not built by default):
+
+- C4D (https://github.com/acgessler/assimp-cinema4d)
+
+__Exporters__:
+
+- DAE (Collada)
+- STL
+- OBJ
+- PLY
+- X
+- 3DS
+- JSON (for WebGl, via https://github.com/acgessler/assimp2json)
+- ASSBIN
+- STEP
+- glTF (partial)
+
+### Building ###
+Take a look into the `INSTALL` file. Our build system is CMake, if you used CMake before there is a good chance you know what to do.
+
+### Ports ###
+* [Android](port/AndroidJNI/README.md)
+* [Python](port/PyAssimp/README.md)
+* [.NET](port/AssimpNET/Readme.md)
+* [Pascal](port/AssimpPascal/Readme.md)
+* [Javascript (Alpha)](https://github.com/makc/assimp2json)
+
+#### Repository structure ####
+Open Asset Import Library is implemented in C++. The directory structure is:
+
+       /code           Source code
+       /contrib        Third-party libraries
+       /doc            Documentation (doxysource and pre-compiled docs)
+       /include        Public header C and C++ header files
+       /scripts        Scripts used to generate the loading code for some formats
+       /port           Ports to other languages and scripts to maintain those.
+       /test           Unit- and regression tests, test suite of models
+       /tools          Tools (old assimp viewer, command line `assimp`)
+       /samples        A small number of samples to illustrate possible
+                        use cases for Assimp
+       /workspaces     Build environments for vc,xcode,... (deprecated,
+                       CMake has superseeded all legacy build options!)
+
+
+### Where to get help ###
+For more information, visit [our website](http://assimp.org/). 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).
+
+If the docs don't solve your problem, ask on [StackOverflow](http://stackoverflow.com/questions/tagged/assimp?sort=newest). If you think you found a bug, please open an issue on Github.
+
+For development discussions, there is also a (very low-volume) mailing list, _assimp-discussions_
+  [(subscribe here)]( https://lists.sourceforge.net/lists/listinfo/assimp-discussions)
+
+Open Asset Import Library is a library to load various 3d file formats into a shared, in-memory format. It supports more than __40 file formats__ for import and a growing selection of file formats for export.
+
+And we also have a Gitter-channel:Gitter [![Join the chat at https://gitter.im/assimp/assimp](https://badges.gitter.im/assimp/assimp.svg)](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)<br>
+
+### Contributing ###
+Contributions to assimp are highly appreciated. The easiest way to get involved is to submit
+a pull request with your changes against the main repository's `master` branch.
+
+### Donate ###
+If you like assimp, consider buying us a beer (or two):
+[Donate](http://sourceforge.net/donate/index.php?group_id=226462)
+
+### License ###
+Our license is based on the modified, __3-clause BSD__-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.
+For the legal details, see the `LICENSE` file.
+
+### Why this name ###
+Sorry, we're germans :-), no english native speakers ...
index b5ed862..b906832 100644 (file)
@@ -44,8 +44,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER
 
-#include "BlenderDNA.h"
 #include "BlenderScene.h"
+#include "BlenderSceneGen.h"
+#include "BlenderDNA.h"
 
 using namespace Assimp;
 using namespace Assimp::Blender;
index 901f5b3..c3934e0 100644 (file)
@@ -44,6 +44,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef INCLUDED_AI_FBX_COMPILECONFIG_H
 #define INCLUDED_AI_FBX_COMPILECONFIG_H
 
+#include <map>
+
 //
 #if _MSC_VER > 1500 || (defined __GNUC___)
 #   define ASSIMP_FBX_USE_UNORDERED_MULTIMAP
index 49ce031..0d5e24f 100644 (file)
@@ -55,7 +55,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #include <memory>
 #include <functional>
-
+#include <map>
 
 namespace Assimp {
 namespace FBX {
index 8e9d40b..6562ef4 100644 (file)
@@ -51,7 +51,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #   include "../contrib/zlib/zlib.h"
 #endif
 
-
 #include "FBXTokenizer.h"
 #include "FBXParser.h"
 #include "FBXUtil.h"
index 303f296..ed7af67 100644 (file)
@@ -46,11 +46,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #include "FBXCompileConfig.h"
 #include <memory>
+#include <string>
 
 namespace Assimp {
 namespace FBX {
 
-    class Element;
+// Forward declarations
+class Element;
 
 
 /** Represents a dynamic property. Type info added by deriving classes,
index 0f020ac..3b60142 100644 (file)
@@ -47,6 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "FBXCompileConfig.h"
 #include <assimp/ai_assert.h>
 #include <vector>
+#include <string>
 
 namespace Assimp {
 namespace FBX {
index 601d5e2..280349d 100644 (file)
@@ -46,6 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "FBXTokenizer.h"
 
 #include "TinyFormatter.h"
+#include <string>
 
 #ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
 
index 78f9d85..0fe98c0 100644 (file)
@@ -1,80 +1,80 @@
-// Microsoft Visual C++ generated resource script.\r
-//\r
-#include "resource.h"\r
-#include "..\..\revision.h"\r
-\r
-#define APSTUDIO_READONLY_SYMBOLS\r
-/////////////////////////////////////////////////////////////////////////////\r
-//\r
-// Generated from the TEXTINCLUDE 2 resource.\r
-//\r
-#define APSTUDIO_HIDDEN_SYMBOLS\r
-#include "windows.h"\r
-#undef APSTUDIO_HIDDEN_SYMBOLS\r
-\r
-/////////////////////////////////////////////////////////////////////////////\r
-#undef APSTUDIO_READONLY_SYMBOLS\r
-\r
-/////////////////////////////////////////////////////////////////////////////\r
-// Deutsch (Deutschland) resources\r
-\r
-#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEU)\r
-#ifdef _WIN32\r
-LANGUAGE LANG_GERMAN, SUBLANG_GERMAN\r
-#pragma code_page(1252)\r
-#endif //_WIN32\r
-\r
-\r
-/////////////////////////////////////////////////////////////////////////////\r
-//\r
-// Version\r
-//\r
-\r
-VS_VERSION_INFO VERSIONINFO\r
- FILEVERSION 1,1,SVNRevision, 0\r
- PRODUCTVERSION 1,1,SVNRevision,0\r
- FILEFLAGSMASK 0x17L\r
-#ifdef _DEBUG\r
- FILEFLAGS 0x1L\r
-#else\r
- FILEFLAGS 0x0L\r
-#endif\r
- FILEOS 0x4L\r
- FILETYPE 0x7L\r
- FILESUBTYPE 0x0L\r
-BEGIN\r
-    BLOCK "StringFileInfo"\r
-    BEGIN\r
-        BLOCK "040704b0"\r
-        BEGIN\r
-            VALUE "Comments", "Licensed under a 3-clause BSD license"\r
-            VALUE "CompanyName", "assimp team"\r
-            VALUE "FileDescription", "Open Asset Import Library"\r
-            VALUE "FileVersion", 1,1,SVNRevision,0\r
-            VALUE "InternalName", "assimp "\r
-            VALUE "LegalCopyright", "Copyright (C) 2006-2010"\r
-            VALUE "OriginalFilename", "assimpNN.dll"\r
-            VALUE "ProductName", "Open Asset Import Library"\r
-            VALUE "ProductVersion", 1,1,SVNRevision,0\r
-               ,0\r
-        END\r
-    END\r
-    BLOCK "VarFileInfo"\r
-    BEGIN\r
-        VALUE "Translation", 0x407, 1200\r
-    END\r
-END\r
-\r
-#endif    // Deutsch (Deutschland) resources\r
-/////////////////////////////////////////////////////////////////////////////\r
-\r
-\r
-#ifndef APSTUDIO_INVOKED\r
-/////////////////////////////////////////////////////////////////////////////\r
-//\r
-// Generated from the TEXTINCLUDE 3 resource.\r
-//\r
-\r
-/////////////////////////////////////////////////////////////////////////////\r
-#endif    // not APSTUDIO_INVOKED\r
-\r
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+#include "..\..\revision.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#define APSTUDIO_HIDDEN_SYMBOLS
+#include "windows.h"
+#undef APSTUDIO_HIDDEN_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Deutsch (Deutschland) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEU)
+#ifdef _WIN32
+LANGUAGE LANG_GERMAN, SUBLANG_GERMAN
+#pragma code_page(1252)
+#endif //_WIN32
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,1,SVNRevision, 0
+ PRODUCTVERSION 1,1,SVNRevision,0
+ FILEFLAGSMASK 0x17L
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x7L
+ FILESUBTYPE 0x0L
+BEGIN
+    BLOCK "StringFileInfo"
+    BEGIN
+        BLOCK "040704b0"
+        BEGIN
+            VALUE "Comments", "Licensed under a 3-clause BSD license"
+            VALUE "CompanyName", "assimp team"
+            VALUE "FileDescription", "Open Asset Import Library"
+            VALUE "FileVersion", 1,1,SVNRevision,0
+            VALUE "InternalName", "assimp "
+            VALUE "LegalCopyright", "Copyright (C) 2006-2010"
+            VALUE "OriginalFilename", "assimpNN.dll"
+            VALUE "ProductName", "Open Asset Import Library"
+            VALUE "ProductVersion", 1,1,SVNRevision,0
+               ,0
+        END
+    END
+    BLOCK "VarFileInfo"
+    BEGIN
+        VALUE "Translation", 0x407, 1200
+    END
+END
+
+#endif    // Deutsch (Deutschland) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+/////////////////////////////////////////////////////////////////////////////
+#endif    // not APSTUDIO_INVOKED
+
index f013e47..d783825 100644 (file)
@@ -1,72 +1,72 @@
-/* \r
- * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors\r
- * http://code.google.com/p/poly2tri/\r
- *\r
- * All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without modification,\r
- * are permitted provided that the following conditions are met:\r
- *\r
- * * Redistributions of source code must retain the above copyright notice,\r
- *   this list of conditions and the following disclaimer.\r
- * * Redistributions in binary form must reproduce the above copyright notice,\r
- *   this list of conditions and the following disclaimer in the documentation\r
- *   and/or other materials provided with the distribution.\r
- * * Neither the name of Poly2Tri nor the names of its contributors may be\r
- *   used to endorse or promote products derived from this software without specific\r
- *   prior written permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\r
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\r
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\r
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-#include "cdt.h"\r
-\r
-namespace p2t {\r
-\r
-CDT::CDT(std::vector<Point*> polyline)\r
-{\r
-  sweep_context_ = new SweepContext(polyline);\r
-  sweep_ = new Sweep;\r
-}\r
-\r
-void CDT::AddHole(std::vector<Point*> polyline)\r
-{\r
-  sweep_context_->AddHole(polyline);\r
-}\r
-\r
-void CDT::AddPoint(Point* point) {\r
-  sweep_context_->AddPoint(point);\r
-}\r
-\r
-void CDT::Triangulate()\r
-{\r
-  sweep_->Triangulate(*sweep_context_);\r
-}\r
-\r
-std::vector<p2t::Triangle*> CDT::GetTriangles()\r
-{\r
-  return sweep_context_->GetTriangles();\r
-}\r
-\r
-std::list<p2t::Triangle*> CDT::GetMap()\r
-{\r
-  return sweep_context_->GetMap();\r
-}\r
-\r
-CDT::~CDT()\r
-{\r
-  delete sweep_context_;\r
-  delete sweep_;\r
-}\r
-\r
-}\r
-\r
+/* 
+ * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
+ * http://code.google.com/p/poly2tri/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "cdt.h"
+
+namespace p2t {
+
+CDT::CDT(std::vector<Point*> polyline)
+{
+  sweep_context_ = new SweepContext(polyline);
+  sweep_ = new Sweep;
+}
+
+void CDT::AddHole(std::vector<Point*> polyline)
+{
+  sweep_context_->AddHole(polyline);
+}
+
+void CDT::AddPoint(Point* point) {
+  sweep_context_->AddPoint(point);
+}
+
+void CDT::Triangulate()
+{
+  sweep_->Triangulate(*sweep_context_);
+}
+
+std::vector<p2t::Triangle*> CDT::GetTriangles()
+{
+  return sweep_context_->GetTriangles();
+}
+
+std::list<p2t::Triangle*> CDT::GetMap()
+{
+  return sweep_context_->GetMap();
+}
+
+CDT::~CDT()
+{
+  delete sweep_context_;
+  delete sweep_;
+}
+
+}
+
index d3e35ae..ed7c49a 100644 (file)
-/*\r
- * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors\r
- * http://code.google.com/p/poly2tri/\r
- *\r
- * All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without modification,\r
- * are permitted provided that the following conditions are met:\r
- *\r
- * * Redistributions of source code must retain the above copyright notice,\r
- *   this list of conditions and the following disclaimer.\r
- * * Redistributions in binary form must reproduce the above copyright notice,\r
- *   this list of conditions and the following disclaimer in the documentation\r
- *   and/or other materials provided with the distribution.\r
- * * Neither the name of Poly2Tri nor the names of its contributors may be\r
- *   used to endorse or promote products derived from this software without specific\r
- *   prior written permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\r
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\r
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\r
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-#include <stdexcept>\r
-#include "sweep.h"\r
-#include "sweep_context.h"\r
-#include "advancing_front.h"\r
-#include "../common/utils.h"\r
-\r
-namespace p2t {\r
-\r
-// Triangulate simple polygon with holes\r
-void Sweep::Triangulate(SweepContext& tcx)\r
-{\r
-  tcx.InitTriangulation();\r
-  tcx.CreateAdvancingFront(nodes_);\r
-  // Sweep points; build mesh\r
-  SweepPoints(tcx);\r
-  // Clean up\r
-  FinalizationPolygon(tcx);\r
-}\r
-\r
-void Sweep::SweepPoints(SweepContext& tcx)\r
-{\r
-  for (int i = 1; i < tcx.point_count(); i++) {\r
-    Point& point = *tcx.GetPoint(i);\r
-    Node* node = &PointEvent(tcx, point);\r
-    for (unsigned int i = 0; i < point.edge_list.size(); i++) {\r
-      EdgeEvent(tcx, point.edge_list[i], node);\r
-    }\r
-  }\r
-}\r
-\r
-void Sweep::FinalizationPolygon(SweepContext& tcx)\r
-{\r
-  // Get an Internal triangle to start with\r
-  Triangle* t = tcx.front()->head()->next->triangle;\r
-  Point* p = tcx.front()->head()->next->point;\r
-  while (!t->GetConstrainedEdgeCW(*p)) {\r
-    t = t->NeighborCCW(*p);\r
-  }\r
-\r
-  // Collect interior triangles constrained by edges\r
-  tcx.MeshClean(*t);\r
-}\r
-\r
-Node& Sweep::PointEvent(SweepContext& tcx, Point& point)\r
-{\r
-  Node& node = tcx.LocateNode(point);\r
-  Node& new_node = NewFrontTriangle(tcx, point, node);\r
-\r
-  // Only need to check +epsilon since point never have smaller\r
-  // x value than node due to how we fetch nodes from the front\r
-  if (point.x <= node.point->x + EPSILON) {\r
-    Fill(tcx, node);\r
-  }\r
-\r
-  //tcx.AddNode(new_node);\r
-\r
-  FillAdvancingFront(tcx, new_node);\r
-  return new_node;\r
-}\r
-\r
-void Sweep::EdgeEvent(SweepContext& tcx, Edge* edge, Node* node)\r
-{\r
-  tcx.edge_event.constrained_edge = edge;\r
-  tcx.edge_event.right = (edge->p->x > edge->q->x);\r
-\r
-  if (IsEdgeSideOfTriangle(*node->triangle, *edge->p, *edge->q)) {\r
-    return;\r
-  }\r
-\r
-  // For now we will do all needed filling\r
-  // TODO: integrate with flip process might give some better performance\r
-  //       but for now this avoid the issue with cases that needs both flips and fills\r
-  FillEdgeEvent(tcx, edge, node);\r
-  EdgeEvent(tcx, *edge->p, *edge->q, node->triangle, *edge->q);\r
-}\r
-\r
-void Sweep::EdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle* triangle, Point& point)\r
-{\r
-  if (IsEdgeSideOfTriangle(*triangle, ep, eq)) {\r
-    return;\r
-  }\r
-\r
-  Point* p1 = triangle->PointCCW(point);\r
-  Orientation o1 = Orient2d(eq, *p1, ep);\r
-  if (o1 == COLLINEAR) {\r
-         // ASSIMP_CHANGE (aramis_acg)\r
-         throw std::runtime_error("EdgeEvent - collinear points not supported");\r
-    if( triangle->Contains(&eq, p1)) {\r
-      triangle->MarkConstrainedEdge(&eq, p1 );\r
-      // We are modifying the constraint maybe it would be better to \r
-      // not change the given constraint and just keep a variable for the new constraint\r
-      tcx.edge_event.constrained_edge->q = p1;\r
-      triangle = &triangle->NeighborAcross(point);\r
-      EdgeEvent( tcx, ep, *p1, triangle, *p1 );\r
-    } else {\r
-         // ASSIMP_CHANGE (aramis_acg)\r
-      std::runtime_error("EdgeEvent - collinear points not supported");\r
-    }\r
-    return;\r
-  }\r
-\r
-  Point* p2 = triangle->PointCW(point);\r
-  Orientation o2 = Orient2d(eq, *p2, ep);\r
-  if (o2 == COLLINEAR) {\r
-         // ASSIMP_CHANGE (aramis_acg)\r
-         throw std::runtime_error("EdgeEvent - collinear points not supported");\r
-\r
-    if( triangle->Contains(&eq, p2)) {\r
-      triangle->MarkConstrainedEdge(&eq, p2 );\r
-      // We are modifying the constraint maybe it would be better to \r
-      // not change the given constraint and just keep a variable for the new constraint\r
-      tcx.edge_event.constrained_edge->q = p2;\r
-      triangle = &triangle->NeighborAcross(point);\r
-      EdgeEvent( tcx, ep, *p2, triangle, *p2 );\r
-    } else {\r
-      // ASSIMP_CHANGE (aramis_acg)\r
-      throw std::runtime_error("EdgeEvent - collinear points not supported");\r
-    }\r
-    return;\r
-  }\r
-\r
-  if (o1 == o2) {\r
-    // Need to decide if we are rotating CW or CCW to get to a triangle\r
-    // that will cross edge\r
-    if (o1 == CW) {\r
-      triangle = triangle->NeighborCCW(point);\r
-    }       else{\r
-      triangle = triangle->NeighborCW(point);\r
-    }\r
-    EdgeEvent(tcx, ep, eq, triangle, point);\r
-  } else {\r
-    // This triangle crosses constraint so lets flippin start!\r
-    FlipEdgeEvent(tcx, ep, eq, triangle, point);\r
-  }\r
-}\r
-\r
-bool Sweep::IsEdgeSideOfTriangle(Triangle& triangle, Point& ep, Point& eq)\r
-{\r
-  int index = triangle.EdgeIndex(&ep, &eq);\r
-\r
-  if (index != -1) {\r
-    triangle.MarkConstrainedEdge(index);\r
-    Triangle* t = triangle.GetNeighbor(index);\r
-    if (t) {\r
-      t->MarkConstrainedEdge(&ep, &eq);\r
-    }\r
-    return true;\r
-  }\r
-  return false;\r
-}\r
-\r
-Node& Sweep::NewFrontTriangle(SweepContext& tcx, Point& point, Node& node)\r
-{\r
-  Triangle* triangle = new Triangle(point, *node.point, *node.next->point);\r
-\r
-  triangle->MarkNeighbor(*node.triangle);\r
-  tcx.AddToMap(triangle);\r
-\r
-  Node* new_node = new Node(point);\r
-  nodes_.push_back(new_node);\r
-\r
-  new_node->next = node.next;\r
-  new_node->prev = &node;\r
-  node.next->prev = new_node;\r
-  node.next = new_node;\r
-\r
-  if (!Legalize(tcx, *triangle)) {\r
-    tcx.MapTriangleToNodes(*triangle);\r
-  }\r
-\r
-  return *new_node;\r
-}\r
-\r
-void Sweep::Fill(SweepContext& tcx, Node& node)\r
-{\r
-  Triangle* triangle = new Triangle(*node.prev->point, *node.point, *node.next->point);\r
-\r
-  // TODO: should copy the constrained_edge value from neighbor triangles\r
-  //       for now constrained_edge values are copied during the legalize\r
-  triangle->MarkNeighbor(*node.prev->triangle);\r
-  triangle->MarkNeighbor(*node.triangle);\r
-\r
-  tcx.AddToMap(triangle);\r
-\r
-  // Update the advancing front\r
-  node.prev->next = node.next;\r
-  node.next->prev = node.prev;\r
-\r
-  // If it was legalized the triangle has already been mapped\r
-  if (!Legalize(tcx, *triangle)) {\r
-    tcx.MapTriangleToNodes(*triangle);\r
-  }\r
-\r
-}\r
-\r
-void Sweep::FillAdvancingFront(SweepContext& tcx, Node& n)\r
-{\r
-\r
-  // Fill right holes\r
-  Node* node = n.next;\r
-\r
-  while (node->next) {\r
-    double angle = HoleAngle(*node);\r
-    if (angle > PI_2 || angle < -PI_2) break;\r
-    Fill(tcx, *node);\r
-    node = node->next;\r
-  }\r
-\r
-  // Fill left holes\r
-  node = n.prev;\r
-\r
-  while (node->prev) {\r
-    double angle = HoleAngle(*node);\r
-    if (angle > PI_2 || angle < -PI_2) break;\r
-    Fill(tcx, *node);\r
-    node = node->prev;\r
-  }\r
-\r
-  // Fill right basins\r
-  if (n.next && n.next->next) {\r
-    double angle = BasinAngle(n);\r
-    if (angle < PI_3div4) {\r
-      FillBasin(tcx, n);\r
-    }\r
-  }\r
-}\r
-\r
-double Sweep::BasinAngle(Node& node)\r
-{\r
-  double ax = node.point->x - node.next->next->point->x;\r
-  double ay = node.point->y - node.next->next->point->y;\r
-  return atan2(ay, ax);\r
-}\r
-\r
-double Sweep::HoleAngle(Node& node)\r
-{\r
-  /* Complex plane\r
-   * ab = cosA +i*sinA\r
-   * ab = (ax + ay*i)(bx + by*i) = (ax*bx + ay*by) + i(ax*by-ay*bx)\r
-   * atan2(y,x) computes the principal value of the argument function\r
-   * applied to the complex number x+iy\r
-   * Where x = ax*bx + ay*by\r
-   *       y = ax*by - ay*bx\r
-   */\r
-  double ax = node.next->point->x - node.point->x;\r
-  double ay = node.next->point->y - node.point->y;\r
-  double bx = node.prev->point->x - node.point->x;\r
-  double by = node.prev->point->y - node.point->y;\r
-  return atan2(ax * by - ay * bx, ax * bx + ay * by);\r
-}\r
-\r
-bool Sweep::Legalize(SweepContext& tcx, Triangle& t)\r
-{\r
-  // To legalize a triangle we start by finding if any of the three edges\r
-  // violate the Delaunay condition\r
-  for (int i = 0; i < 3; i++) {\r
-    if (t.delaunay_edge[i])\r
-      continue;\r
-\r
-    Triangle* ot = t.GetNeighbor(i);\r
-\r
-    if (ot) {\r
-      Point* p = t.GetPoint(i);\r
-      Point* op = ot->OppositePoint(t, *p);\r
-      int oi = ot->Index(op);\r
-\r
-      // If this is a Constrained Edge or a Delaunay Edge(only during recursive legalization)\r
-      // then we should not try to legalize\r
-      if (ot->constrained_edge[oi] || ot->delaunay_edge[oi]) {\r
-        t.constrained_edge[i] = ot->constrained_edge[oi];\r
-        continue;\r
-      }\r
-\r
-      bool inside = Incircle(*p, *t.PointCCW(*p), *t.PointCW(*p), *op);\r
-\r
-      if (inside) {\r
-        // Lets mark this shared edge as Delaunay\r
-        t.delaunay_edge[i] = true;\r
-        ot->delaunay_edge[oi] = true;\r
-\r
-        // Lets rotate shared edge one vertex CW to legalize it\r
-        RotateTrianglePair(t, *p, *ot, *op);\r
-\r
-        // We now got one valid Delaunay Edge shared by two triangles\r
-        // This gives us 4 new edges to check for Delaunay\r
-\r
-        // Make sure that triangle to node mapping is done only one time for a specific triangle\r
-        bool not_legalized = !Legalize(tcx, t);\r
-        if (not_legalized) {\r
-          tcx.MapTriangleToNodes(t);\r
-        }\r
-\r
-        not_legalized = !Legalize(tcx, *ot);\r
-        if (not_legalized)\r
-          tcx.MapTriangleToNodes(*ot);\r
-\r
-        // Reset the Delaunay edges, since they only are valid Delaunay edges\r
-        // until we add a new triangle or point.\r
-        // XXX: need to think about this. Can these edges be tried after we\r
-        //      return to previous recursive level?\r
-        t.delaunay_edge[i] = false;\r
-        ot->delaunay_edge[oi] = false;\r
-\r
-        // If triangle have been legalized no need to check the other edges since\r
-        // the recursive legalization will handles those so we can end here.\r
-        return true;\r
-      }\r
-    }\r
-  }\r
-  return false;\r
-}\r
-\r
-bool Sweep::Incircle(Point& pa, Point& pb, Point& pc, Point& pd)\r
-{\r
-  double adx = pa.x - pd.x;\r
-  double ady = pa.y - pd.y;\r
-  double bdx = pb.x - pd.x;\r
-  double bdy = pb.y - pd.y;\r
-\r
-  double adxbdy = adx * bdy;\r
-  double bdxady = bdx * ady;\r
-  double oabd = adxbdy - bdxady;\r
-\r
-  if (oabd <= 0)\r
-    return false;\r
-\r
-  double cdx = pc.x - pd.x;\r
-  double cdy = pc.y - pd.y;\r
-\r
-  double cdxady = cdx * ady;\r
-  double adxcdy = adx * cdy;\r
-  double ocad = cdxady - adxcdy;\r
-\r
-  if (ocad <= 0)\r
-    return false;\r
-\r
-  double bdxcdy = bdx * cdy;\r
-  double cdxbdy = cdx * bdy;\r
-\r
-  double alift = adx * adx + ady * ady;\r
-  double blift = bdx * bdx + bdy * bdy;\r
-  double clift = cdx * cdx + cdy * cdy;\r
-\r
-  double det = alift * (bdxcdy - cdxbdy) + blift * ocad + clift * oabd;\r
-\r
-  return det > 0;\r
-}\r
-\r
-void Sweep::RotateTrianglePair(Triangle& t, Point& p, Triangle& ot, Point& op)\r
-{\r
-  Triangle* n1, *n2, *n3, *n4;\r
-  n1 = t.NeighborCCW(p);\r
-  n2 = t.NeighborCW(p);\r
-  n3 = ot.NeighborCCW(op);\r
-  n4 = ot.NeighborCW(op);\r
-\r
-  bool ce1, ce2, ce3, ce4;\r
-  ce1 = t.GetConstrainedEdgeCCW(p);\r
-  ce2 = t.GetConstrainedEdgeCW(p);\r
-  ce3 = ot.GetConstrainedEdgeCCW(op);\r
-  ce4 = ot.GetConstrainedEdgeCW(op);\r
-\r
-  bool de1, de2, de3, de4;\r
-  de1 = t.GetDelunayEdgeCCW(p);\r
-  de2 = t.GetDelunayEdgeCW(p);\r
-  de3 = ot.GetDelunayEdgeCCW(op);\r
-  de4 = ot.GetDelunayEdgeCW(op);\r
-\r
-  t.Legalize(p, op);\r
-  ot.Legalize(op, p);\r
-\r
-  // Remap delaunay_edge\r
-  ot.SetDelunayEdgeCCW(p, de1);\r
-  t.SetDelunayEdgeCW(p, de2);\r
-  t.SetDelunayEdgeCCW(op, de3);\r
-  ot.SetDelunayEdgeCW(op, de4);\r
-\r
-  // Remap constrained_edge\r
-  ot.SetConstrainedEdgeCCW(p, ce1);\r
-  t.SetConstrainedEdgeCW(p, ce2);\r
-  t.SetConstrainedEdgeCCW(op, ce3);\r
-  ot.SetConstrainedEdgeCW(op, ce4);\r
-\r
-  // Remap neighbors\r
-  // XXX: might optimize the markNeighbor by keeping track of\r
-  //      what side should be assigned to what neighbor after the\r
-  //      rotation. Now mark neighbor does lots of testing to find\r
-  //      the right side.\r
-  t.ClearNeighbors();\r
-  ot.ClearNeighbors();\r
-  if (n1) ot.MarkNeighbor(*n1);\r
-  if (n2) t.MarkNeighbor(*n2);\r
-  if (n3) t.MarkNeighbor(*n3);\r
-  if (n4) ot.MarkNeighbor(*n4);\r
-  t.MarkNeighbor(ot);\r
-}\r
-\r
-void Sweep::FillBasin(SweepContext& tcx, Node& node)\r
-{\r
-  if (Orient2d(*node.point, *node.next->point, *node.next->next->point) == CCW) {\r
-    tcx.basin.left_node = node.next->next;\r
-  } else {\r
-    tcx.basin.left_node = node.next;\r
-  }\r
-\r
-  // Find the bottom and right node\r
-  tcx.basin.bottom_node = tcx.basin.left_node;\r
-  while (tcx.basin.bottom_node->next\r
-         && tcx.basin.bottom_node->point->y >= tcx.basin.bottom_node->next->point->y) {\r
-    tcx.basin.bottom_node = tcx.basin.bottom_node->next;\r
-  }\r
-  if (tcx.basin.bottom_node == tcx.basin.left_node) {\r
-    // No valid basin\r
-    return;\r
-  }\r
-\r
-  tcx.basin.right_node = tcx.basin.bottom_node;\r
-  while (tcx.basin.right_node->next\r
-         && tcx.basin.right_node->point->y < tcx.basin.right_node->next->point->y) {\r
-    tcx.basin.right_node = tcx.basin.right_node->next;\r
-  }\r
-  if (tcx.basin.right_node == tcx.basin.bottom_node) {\r
-    // No valid basins\r
-    return;\r
-  }\r
-\r
-  tcx.basin.width = tcx.basin.right_node->point->x - tcx.basin.left_node->point->x;\r
-  tcx.basin.left_highest = tcx.basin.left_node->point->y > tcx.basin.right_node->point->y;\r
-\r
-  FillBasinReq(tcx, tcx.basin.bottom_node);\r
-}\r
-\r
-void Sweep::FillBasinReq(SweepContext& tcx, Node* node)\r
-{\r
-  // if shallow stop filling\r
-  if (IsShallow(tcx, *node)) {\r
-    return;\r
-  }\r
-\r
-  Fill(tcx, *node);\r
-\r
-  if (node->prev == tcx.basin.left_node && node->next == tcx.basin.right_node) {\r
-    return;\r
-  } else if (node->prev == tcx.basin.left_node) {\r
-    Orientation o = Orient2d(*node->point, *node->next->point, *node->next->next->point);\r
-    if (o == CW) {\r
-      return;\r
-    }\r
-    node = node->next;\r
-  } else if (node->next == tcx.basin.right_node) {\r
-    Orientation o = Orient2d(*node->point, *node->prev->point, *node->prev->prev->point);\r
-    if (o == CCW) {\r
-      return;\r
-    }\r
-    node = node->prev;\r
-  } else {\r
-    // Continue with the neighbor node with lowest Y value\r
-    if (node->prev->point->y < node->next->point->y) {\r
-      node = node->prev;\r
-    } else {\r
-      node = node->next;\r
-    }\r
-  }\r
-\r
-  FillBasinReq(tcx, node);\r
-}\r
-\r
-bool Sweep::IsShallow(SweepContext& tcx, Node& node)\r
-{\r
-  double height;\r
-\r
-  if (tcx.basin.left_highest) {\r
-    height = tcx.basin.left_node->point->y - node.point->y;\r
-  } else {\r
-    height = tcx.basin.right_node->point->y - node.point->y;\r
-  }\r
-\r
-  // if shallow stop filling\r
-  if (tcx.basin.width > height) {\r
-    return true;\r
-  }\r
-  return false;\r
-}\r
-\r
-void Sweep::FillEdgeEvent(SweepContext& tcx, Edge* edge, Node* node)\r
-{\r
-  if (tcx.edge_event.right) {\r
-    FillRightAboveEdgeEvent(tcx, edge, node);\r
-  } else {\r
-    FillLeftAboveEdgeEvent(tcx, edge, node);\r
-  }\r
-}\r
-\r
-void Sweep::FillRightAboveEdgeEvent(SweepContext& tcx, Edge* edge, Node* node)\r
-{\r
-  while (node->next->point->x < edge->p->x) {\r
-    // Check if next node is below the edge\r
-    if (Orient2d(*edge->q, *node->next->point, *edge->p) == CCW) {\r
-      FillRightBelowEdgeEvent(tcx, edge, *node);\r
-    } else {\r
-      node = node->next;\r
-    }\r
-  }\r
-}\r
-\r
-void Sweep::FillRightBelowEdgeEvent(SweepContext& tcx, Edge* edge, Node& node)\r
-{\r
-  if (node.point->x < edge->p->x) {\r
-    if (Orient2d(*node.point, *node.next->point, *node.next->next->point) == CCW) {\r
-      // Concave\r
-      FillRightConcaveEdgeEvent(tcx, edge, node);\r
-    } else{\r
-      // Convex\r
-      FillRightConvexEdgeEvent(tcx, edge, node);\r
-      // Retry this one\r
-      FillRightBelowEdgeEvent(tcx, edge, node);\r
-    }\r
-  }\r
-}\r
-\r
-void Sweep::FillRightConcaveEdgeEvent(SweepContext& tcx, Edge* edge, Node& node)\r
-{\r
-  Fill(tcx, *node.next);\r
-  if (node.next->point != edge->p) {\r
-    // Next above or below edge?\r
-    if (Orient2d(*edge->q, *node.next->point, *edge->p) == CCW) {\r
-      // Below\r
-      if (Orient2d(*node.point, *node.next->point, *node.next->next->point) == CCW) {\r
-        // Next is concave\r
-        FillRightConcaveEdgeEvent(tcx, edge, node);\r
-      } else {\r
-        // Next is convex\r
-      }\r
-    }\r
-  }\r
-\r
-}\r
-\r
-void Sweep::FillRightConvexEdgeEvent(SweepContext& tcx, Edge* edge, Node& node)\r
-{\r
-  // Next concave or convex?\r
-  if (Orient2d(*node.next->point, *node.next->next->point, *node.next->next->next->point) == CCW) {\r
-    // Concave\r
-    FillRightConcaveEdgeEvent(tcx, edge, *node.next);\r
-  } else{\r
-    // Convex\r
-    // Next above or below edge?\r
-    if (Orient2d(*edge->q, *node.next->next->point, *edge->p) == CCW) {\r
-      // Below\r
-      FillRightConvexEdgeEvent(tcx, edge, *node.next);\r
-    } else{\r
-      // Above\r
-    }\r
-  }\r
-}\r
-\r
-void Sweep::FillLeftAboveEdgeEvent(SweepContext& tcx, Edge* edge, Node* node)\r
-{\r
-  while (node->prev->point->x > edge->p->x) {\r
-    // Check if next node is below the edge\r
-    if (Orient2d(*edge->q, *node->prev->point, *edge->p) == CW) {\r
-      FillLeftBelowEdgeEvent(tcx, edge, *node);\r
-    } else {\r
-      node = node->prev;\r
-    }\r
-  }\r
-}\r
-\r
-void Sweep::FillLeftBelowEdgeEvent(SweepContext& tcx, Edge* edge, Node& node)\r
-{\r
-  if (node.point->x > edge->p->x) {\r
-    if (Orient2d(*node.point, *node.prev->point, *node.prev->prev->point) == CW) {\r
-      // Concave\r
-      FillLeftConcaveEdgeEvent(tcx, edge, node);\r
-    } else {\r
-      // Convex\r
-      FillLeftConvexEdgeEvent(tcx, edge, node);\r
-      // Retry this one\r
-      FillLeftBelowEdgeEvent(tcx, edge, node);\r
-    }\r
-  }\r
-}\r
-\r
-void Sweep::FillLeftConvexEdgeEvent(SweepContext& tcx, Edge* edge, Node& node)\r
-{\r
-  // Next concave or convex?\r
-  if (Orient2d(*node.prev->point, *node.prev->prev->point, *node.prev->prev->prev->point) == CW) {\r
-    // Concave\r
-    FillLeftConcaveEdgeEvent(tcx, edge, *node.prev);\r
-  } else{\r
-    // Convex\r
-    // Next above or below edge?\r
-    if (Orient2d(*edge->q, *node.prev->prev->point, *edge->p) == CW) {\r
-      // Below\r
-      FillLeftConvexEdgeEvent(tcx, edge, *node.prev);\r
-    } else{\r
-      // Above\r
-    }\r
-  }\r
-}\r
-\r
-void Sweep::FillLeftConcaveEdgeEvent(SweepContext& tcx, Edge* edge, Node& node)\r
-{\r
-  Fill(tcx, *node.prev);\r
-  if (node.prev->point != edge->p) {\r
-    // Next above or below edge?\r
-    if (Orient2d(*edge->q, *node.prev->point, *edge->p) == CW) {\r
-      // Below\r
-      if (Orient2d(*node.point, *node.prev->point, *node.prev->prev->point) == CW) {\r
-        // Next is concave\r
-        FillLeftConcaveEdgeEvent(tcx, edge, node);\r
-      } else{\r
-        // Next is convex\r
-      }\r
-    }\r
-  }\r
-\r
-}\r
-\r
-void Sweep::FlipEdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle* t, Point& p)\r
-{\r
-  Triangle& ot = t->NeighborAcross(p);\r
-  Point& op = *ot.OppositePoint(*t, p);\r
-\r
-  if (InScanArea(p, *t->PointCCW(p), *t->PointCW(p), op)) {\r
-    // Lets rotate shared edge one vertex CW\r
-    RotateTrianglePair(*t, p, ot, op);\r
-    tcx.MapTriangleToNodes(*t);\r
-    tcx.MapTriangleToNodes(ot);\r
-\r
-    if (p == eq && op == ep) {\r
-      if (eq == *tcx.edge_event.constrained_edge->q && ep == *tcx.edge_event.constrained_edge->p) {\r
-        t->MarkConstrainedEdge(&ep, &eq);\r
-        ot.MarkConstrainedEdge(&ep, &eq);\r
-        Legalize(tcx, *t);\r
-        Legalize(tcx, ot);\r
-      } else {\r
-        // XXX: I think one of the triangles should be legalized here?\r
-      }\r
-    } else {\r
-      Orientation o = Orient2d(eq, op, ep);\r
-      t = &NextFlipTriangle(tcx, (int)o, *t, ot, p, op);\r
-      FlipEdgeEvent(tcx, ep, eq, t, p);\r
-    }\r
-  } else {\r
-    Point& newP = NextFlipPoint(ep, eq, ot, op);\r
-    FlipScanEdgeEvent(tcx, ep, eq, *t, ot, newP);\r
-    EdgeEvent(tcx, ep, eq, t, p);\r
-  }\r
-}\r
-\r
-Triangle& Sweep::NextFlipTriangle(SweepContext& tcx, int o, Triangle& t, Triangle& ot, Point& p, Point& op)\r
-{\r
-  if (o == CCW) {\r
-    // ot is not crossing edge after flip\r
-    int edge_index = ot.EdgeIndex(&p, &op);\r
-    ot.delaunay_edge[edge_index] = true;\r
-    Legalize(tcx, ot);\r
-    ot.ClearDelunayEdges();\r
-    return t;\r
-  }\r
-\r
-  // t is not crossing edge after flip\r
-  int edge_index = t.EdgeIndex(&p, &op);\r
-\r
-  t.delaunay_edge[edge_index] = true;\r
-  Legalize(tcx, t);\r
-  t.ClearDelunayEdges();\r
-  return ot;\r
-}\r
-\r
-Point& Sweep::NextFlipPoint(Point& ep, Point& eq, Triangle& ot, Point& op)\r
-{\r
-  Orientation o2d = Orient2d(eq, op, ep);\r
-  if (o2d == CW) {\r
-    // Right\r
-    return *ot.PointCCW(op);\r
-  } else if (o2d == CCW) {\r
-    // Left\r
-    return *ot.PointCW(op);\r
-  } else{\r
-    //throw new RuntimeException("[Unsupported] Opposing point on constrained edge");\r
-         // ASSIMP_CHANGE (aramis_acg)\r
-         throw std::runtime_error("[Unsupported] Opposing point on constrained edge");\r
-  }\r
-}\r
-\r
-void Sweep::FlipScanEdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle& flip_triangle,\r
-                              Triangle& t, Point& p)\r
-{\r
-  Triangle& ot = t.NeighborAcross(p);\r
-  Point& op = *ot.OppositePoint(t, p);\r
-\r
-  if (InScanArea(eq, *flip_triangle.PointCCW(eq), *flip_triangle.PointCW(eq), op)) {\r
-    // flip with new edge op->eq\r
-    FlipEdgeEvent(tcx, eq, op, &ot, op);\r
-    // TODO: Actually I just figured out that it should be possible to\r
-    //       improve this by getting the next ot and op before the the above\r
-    //       flip and continue the flipScanEdgeEvent here\r
-    // set new ot and op here and loop back to inScanArea test\r
-    // also need to set a new flip_triangle first\r
-    // Turns out at first glance that this is somewhat complicated\r
-    // so it will have to wait.\r
-  } else{\r
-    Point& newP = NextFlipPoint(ep, eq, ot, op);\r
-    FlipScanEdgeEvent(tcx, ep, eq, flip_triangle, ot, newP);\r
-  }\r
-}\r
-\r
-Sweep::~Sweep() {\r
-\r
-    // Clean up memory\r
-    for(unsigned int i = 0; i < nodes_.size(); i++) {\r
-        delete nodes_[i];\r
-    }\r
-\r
-}\r
-\r
-}\r
-\r
+/*
+ * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
+ * http://code.google.com/p/poly2tri/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <stdexcept>
+#include "sweep.h"
+#include "sweep_context.h"
+#include "advancing_front.h"
+#include "../common/utils.h"
+
+namespace p2t {
+
+// Triangulate simple polygon with holes
+void Sweep::Triangulate(SweepContext& tcx)
+{
+  tcx.InitTriangulation();
+  tcx.CreateAdvancingFront(nodes_);
+  // Sweep points; build mesh
+  SweepPoints(tcx);
+  // Clean up
+  FinalizationPolygon(tcx);
+}
+
+void Sweep::SweepPoints(SweepContext& tcx)
+{
+  for (int i = 1; i < tcx.point_count(); i++) {
+    Point& point = *tcx.GetPoint(i);
+    Node* node = &PointEvent(tcx, point);
+    for (unsigned int i = 0; i < point.edge_list.size(); i++) {
+      EdgeEvent(tcx, point.edge_list[i], node);
+    }
+  }
+}
+
+void Sweep::FinalizationPolygon(SweepContext& tcx)
+{
+  // Get an Internal triangle to start with
+  Triangle* t = tcx.front()->head()->next->triangle;
+  Point* p = tcx.front()->head()->next->point;
+  while (!t->GetConstrainedEdgeCW(*p)) {
+    t = t->NeighborCCW(*p);
+  }
+
+  // Collect interior triangles constrained by edges
+  tcx.MeshClean(*t);
+}
+
+Node& Sweep::PointEvent(SweepContext& tcx, Point& point)
+{
+  Node& node = tcx.LocateNode(point);
+  Node& new_node = NewFrontTriangle(tcx, point, node);
+
+  // Only need to check +epsilon since point never have smaller
+  // x value than node due to how we fetch nodes from the front
+  if (point.x <= node.point->x + EPSILON) {
+    Fill(tcx, node);
+  }
+
+  //tcx.AddNode(new_node);
+
+  FillAdvancingFront(tcx, new_node);
+  return new_node;
+}
+
+void Sweep::EdgeEvent(SweepContext& tcx, Edge* edge, Node* node)
+{
+  tcx.edge_event.constrained_edge = edge;
+  tcx.edge_event.right = (edge->p->x > edge->q->x);
+
+  if (IsEdgeSideOfTriangle(*node->triangle, *edge->p, *edge->q)) {
+    return;
+  }
+
+  // For now we will do all needed filling
+  // TODO: integrate with flip process might give some better performance
+  //       but for now this avoid the issue with cases that needs both flips and fills
+  FillEdgeEvent(tcx, edge, node);
+  EdgeEvent(tcx, *edge->p, *edge->q, node->triangle, *edge->q);
+}
+
+void Sweep::EdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle* triangle, Point& point)
+{
+  if (IsEdgeSideOfTriangle(*triangle, ep, eq)) {
+    return;
+  }
+
+  Point* p1 = triangle->PointCCW(point);
+  Orientation o1 = Orient2d(eq, *p1, ep);
+  if (o1 == COLLINEAR) {
+         // ASSIMP_CHANGE (aramis_acg)
+         throw std::runtime_error("EdgeEvent - collinear points not supported");
+    if( triangle->Contains(&eq, p1)) {
+      triangle->MarkConstrainedEdge(&eq, p1 );
+      // We are modifying the constraint maybe it would be better to 
+      // not change the given constraint and just keep a variable for the new constraint
+      tcx.edge_event.constrained_edge->q = p1;
+      triangle = &triangle->NeighborAcross(point);
+      EdgeEvent( tcx, ep, *p1, triangle, *p1 );
+    } else {
+         // ASSIMP_CHANGE (aramis_acg)
+      std::runtime_error("EdgeEvent - collinear points not supported");
+    }
+    return;
+  }
+
+  Point* p2 = triangle->PointCW(point);
+  Orientation o2 = Orient2d(eq, *p2, ep);
+  if (o2 == COLLINEAR) {
+         // ASSIMP_CHANGE (aramis_acg)
+         throw std::runtime_error("EdgeEvent - collinear points not supported");
+
+    if( triangle->Contains(&eq, p2)) {
+      triangle->MarkConstrainedEdge(&eq, p2 );
+      // We are modifying the constraint maybe it would be better to 
+      // not change the given constraint and just keep a variable for the new constraint
+      tcx.edge_event.constrained_edge->q = p2;
+      triangle = &triangle->NeighborAcross(point);
+      EdgeEvent( tcx, ep, *p2, triangle, *p2 );
+    } else {
+      // ASSIMP_CHANGE (aramis_acg)
+      throw std::runtime_error("EdgeEvent - collinear points not supported");
+    }
+    return;
+  }
+
+  if (o1 == o2) {
+    // Need to decide if we are rotating CW or CCW to get to a triangle
+    // that will cross edge
+    if (o1 == CW) {
+      triangle = triangle->NeighborCCW(point);
+    }       else{
+      triangle = triangle->NeighborCW(point);
+    }
+    EdgeEvent(tcx, ep, eq, triangle, point);
+  } else {
+    // This triangle crosses constraint so lets flippin start!
+    FlipEdgeEvent(tcx, ep, eq, triangle, point);
+  }
+}
+
+bool Sweep::IsEdgeSideOfTriangle(Triangle& triangle, Point& ep, Point& eq)
+{
+  int index = triangle.EdgeIndex(&ep, &eq);
+
+  if (index != -1) {
+    triangle.MarkConstrainedEdge(index);
+    Triangle* t = triangle.GetNeighbor(index);
+    if (t) {
+      t->MarkConstrainedEdge(&ep, &eq);
+    }
+    return true;
+  }
+  return false;
+}
+
+Node& Sweep::NewFrontTriangle(SweepContext& tcx, Point& point, Node& node)
+{
+  Triangle* triangle = new Triangle(point, *node.point, *node.next->point);
+
+  triangle->MarkNeighbor(*node.triangle);
+  tcx.AddToMap(triangle);
+
+  Node* new_node = new Node(point);
+  nodes_.push_back(new_node);
+
+  new_node->next = node.next;
+  new_node->prev = &node;
+  node.next->prev = new_node;
+  node.next = new_node;
+
+  if (!Legalize(tcx, *triangle)) {
+    tcx.MapTriangleToNodes(*triangle);
+  }
+
+  return *new_node;
+}
+
+void Sweep::Fill(SweepContext& tcx, Node& node)
+{
+  Triangle* triangle = new Triangle(*node.prev->point, *node.point, *node.next->point);
+
+  // TODO: should copy the constrained_edge value from neighbor triangles
+  //       for now constrained_edge values are copied during the legalize
+  triangle->MarkNeighbor(*node.prev->triangle);
+  triangle->MarkNeighbor(*node.triangle);
+
+  tcx.AddToMap(triangle);
+
+  // Update the advancing front
+  node.prev->next = node.next;
+  node.next->prev = node.prev;
+
+  // If it was legalized the triangle has already been mapped
+  if (!Legalize(tcx, *triangle)) {
+    tcx.MapTriangleToNodes(*triangle);
+  }
+
+}
+
+void Sweep::FillAdvancingFront(SweepContext& tcx, Node& n)
+{
+
+  // Fill right holes
+  Node* node = n.next;
+
+  while (node->next) {
+    double angle = HoleAngle(*node);
+    if (angle > PI_2 || angle < -PI_2) break;
+    Fill(tcx, *node);
+    node = node->next;
+  }
+
+  // Fill left holes
+  node = n.prev;
+
+  while (node->prev) {
+    double angle = HoleAngle(*node);
+    if (angle > PI_2 || angle < -PI_2) break;
+    Fill(tcx, *node);
+    node = node->prev;
+  }
+
+  // Fill right basins
+  if (n.next && n.next->next) {
+    double angle = BasinAngle(n);
+    if (angle < PI_3div4) {
+      FillBasin(tcx, n);
+    }
+  }
+}
+
+double Sweep::BasinAngle(Node& node)
+{
+  double ax = node.point->x - node.next->next->point->x;
+  double ay = node.point->y - node.next->next->point->y;
+  return atan2(ay, ax);
+}
+
+double Sweep::HoleAngle(Node& node)
+{
+  /* Complex plane
+   * ab = cosA +i*sinA
+   * ab = (ax + ay*i)(bx + by*i) = (ax*bx + ay*by) + i(ax*by-ay*bx)
+   * atan2(y,x) computes the principal value of the argument function
+   * applied to the complex number x+iy
+   * Where x = ax*bx + ay*by
+   *       y = ax*by - ay*bx
+   */
+  double ax = node.next->point->x - node.point->x;
+  double ay = node.next->point->y - node.point->y;
+  double bx = node.prev->point->x - node.point->x;
+  double by = node.prev->point->y - node.point->y;
+  return atan2(ax * by - ay * bx, ax * bx + ay * by);
+}
+
+bool Sweep::Legalize(SweepContext& tcx, Triangle& t)
+{
+  // To legalize a triangle we start by finding if any of the three edges
+  // violate the Delaunay condition
+  for (int i = 0; i < 3; i++) {
+    if (t.delaunay_edge[i])
+      continue;
+
+    Triangle* ot = t.GetNeighbor(i);
+
+    if (ot) {
+      Point* p = t.GetPoint(i);
+      Point* op = ot->OppositePoint(t, *p);
+      int oi = ot->Index(op);
+
+      // If this is a Constrained Edge or a Delaunay Edge(only during recursive legalization)
+      // then we should not try to legalize
+      if (ot->constrained_edge[oi] || ot->delaunay_edge[oi]) {
+        t.constrained_edge[i] = ot->constrained_edge[oi];
+        continue;
+      }
+
+      bool inside = Incircle(*p, *t.PointCCW(*p), *t.PointCW(*p), *op);
+
+      if (inside) {
+        // Lets mark this shared edge as Delaunay
+        t.delaunay_edge[i] = true;
+        ot->delaunay_edge[oi] = true;
+
+        // Lets rotate shared edge one vertex CW to legalize it
+        RotateTrianglePair(t, *p, *ot, *op);
+
+        // We now got one valid Delaunay Edge shared by two triangles
+        // This gives us 4 new edges to check for Delaunay
+
+        // Make sure that triangle to node mapping is done only one time for a specific triangle
+        bool not_legalized = !Legalize(tcx, t);
+        if (not_legalized) {
+          tcx.MapTriangleToNodes(t);
+        }
+
+        not_legalized = !Legalize(tcx, *ot);
+        if (not_legalized)
+          tcx.MapTriangleToNodes(*ot);
+
+        // Reset the Delaunay edges, since they only are valid Delaunay edges
+        // until we add a new triangle or point.
+        // XXX: need to think about this. Can these edges be tried after we
+        //      return to previous recursive level?
+        t.delaunay_edge[i] = false;
+        ot->delaunay_edge[oi] = false;
+
+        // If triangle have been legalized no need to check the other edges since
+        // the recursive legalization will handles those so we can end here.
+        return true;
+      }
+    }
+  }
+  return false;
+}
+
+bool Sweep::Incircle(Point& pa, Point& pb, Point& pc, Point& pd)
+{
+  double adx = pa.x - pd.x;
+  double ady = pa.y - pd.y;
+  double bdx = pb.x - pd.x;
+  double bdy = pb.y - pd.y;
+
+  double adxbdy = adx * bdy;
+  double bdxady = bdx * ady;
+  double oabd = adxbdy - bdxady;
+
+  if (oabd <= 0)
+    return false;
+
+  double cdx = pc.x - pd.x;
+  double cdy = pc.y - pd.y;
+
+  double cdxady = cdx * ady;
+  double adxcdy = adx * cdy;
+  double ocad = cdxady - adxcdy;
+
+  if (ocad <= 0)
+    return false;
+
+  double bdxcdy = bdx * cdy;
+  double cdxbdy = cdx * bdy;
+
+  double alift = adx * adx + ady * ady;
+  double blift = bdx * bdx + bdy * bdy;
+  double clift = cdx * cdx + cdy * cdy;
+
+  double det = alift * (bdxcdy - cdxbdy) + blift * ocad + clift * oabd;
+
+  return det > 0;
+}
+
+void Sweep::RotateTrianglePair(Triangle& t, Point& p, Triangle& ot, Point& op)
+{
+  Triangle* n1, *n2, *n3, *n4;
+  n1 = t.NeighborCCW(p);
+  n2 = t.NeighborCW(p);
+  n3 = ot.NeighborCCW(op);
+  n4 = ot.NeighborCW(op);
+
+  bool ce1, ce2, ce3, ce4;
+  ce1 = t.GetConstrainedEdgeCCW(p);
+  ce2 = t.GetConstrainedEdgeCW(p);
+  ce3 = ot.GetConstrainedEdgeCCW(op);
+  ce4 = ot.GetConstrainedEdgeCW(op);
+
+  bool de1, de2, de3, de4;
+  de1 = t.GetDelunayEdgeCCW(p);
+  de2 = t.GetDelunayEdgeCW(p);
+  de3 = ot.GetDelunayEdgeCCW(op);
+  de4 = ot.GetDelunayEdgeCW(op);
+
+  t.Legalize(p, op);
+  ot.Legalize(op, p);
+
+  // Remap delaunay_edge
+  ot.SetDelunayEdgeCCW(p, de1);
+  t.SetDelunayEdgeCW(p, de2);
+  t.SetDelunayEdgeCCW(op, de3);
+  ot.SetDelunayEdgeCW(op, de4);
+
+  // Remap constrained_edge
+  ot.SetConstrainedEdgeCCW(p, ce1);
+  t.SetConstrainedEdgeCW(p, ce2);
+  t.SetConstrainedEdgeCCW(op, ce3);
+  ot.SetConstrainedEdgeCW(op, ce4);
+
+  // Remap neighbors
+  // XXX: might optimize the markNeighbor by keeping track of
+  //      what side should be assigned to what neighbor after the
+  //      rotation. Now mark neighbor does lots of testing to find
+  //      the right side.
+  t.ClearNeighbors();
+  ot.ClearNeighbors();
+  if (n1) ot.MarkNeighbor(*n1);
+  if (n2) t.MarkNeighbor(*n2);
+  if (n3) t.MarkNeighbor(*n3);
+  if (n4) ot.MarkNeighbor(*n4);
+  t.MarkNeighbor(ot);
+}
+
+void Sweep::FillBasin(SweepContext& tcx, Node& node)
+{
+  if (Orient2d(*node.point, *node.next->point, *node.next->next->point) == CCW) {
+    tcx.basin.left_node = node.next->next;
+  } else {
+    tcx.basin.left_node = node.next;
+  }
+
+  // Find the bottom and right node
+  tcx.basin.bottom_node = tcx.basin.left_node;
+  while (tcx.basin.bottom_node->next
+         && tcx.basin.bottom_node->point->y >= tcx.basin.bottom_node->next->point->y) {
+    tcx.basin.bottom_node = tcx.basin.bottom_node->next;
+  }
+  if (tcx.basin.bottom_node == tcx.basin.left_node) {
+    // No valid basin
+    return;
+  }
+
+  tcx.basin.right_node = tcx.basin.bottom_node;
+  while (tcx.basin.right_node->next
+         && tcx.basin.right_node->point->y < tcx.basin.right_node->next->point->y) {
+    tcx.basin.right_node = tcx.basin.right_node->next;
+  }
+  if (tcx.basin.right_node == tcx.basin.bottom_node) {
+    // No valid basins
+    return;
+  }
+
+  tcx.basin.width = tcx.basin.right_node->point->x - tcx.basin.left_node->point->x;
+  tcx.basin.left_highest = tcx.basin.left_node->point->y > tcx.basin.right_node->point->y;
+
+  FillBasinReq(tcx, tcx.basin.bottom_node);
+}
+
+void Sweep::FillBasinReq(SweepContext& tcx, Node* node)
+{
+  // if shallow stop filling
+  if (IsShallow(tcx, *node)) {
+    return;
+  }
+
+  Fill(tcx, *node);
+
+  if (node->prev == tcx.basin.left_node && node->next == tcx.basin.right_node) {
+    return;
+  } else if (node->prev == tcx.basin.left_node) {
+    Orientation o = Orient2d(*node->point, *node->next->point, *node->next->next->point);
+    if (o == CW) {
+      return;
+    }
+    node = node->next;
+  } else if (node->next == tcx.basin.right_node) {
+    Orientation o = Orient2d(*node->point, *node->prev->point, *node->prev->prev->point);
+    if (o == CCW) {
+      return;
+    }
+    node = node->prev;
+  } else {
+    // Continue with the neighbor node with lowest Y value
+    if (node->prev->point->y < node->next->point->y) {
+      node = node->prev;
+    } else {
+      node = node->next;
+    }
+  }
+
+  FillBasinReq(tcx, node);
+}
+
+bool Sweep::IsShallow(SweepContext& tcx, Node& node)
+{
+  double height;
+
+  if (tcx.basin.left_highest) {
+    height = tcx.basin.left_node->point->y - node.point->y;
+  } else {
+    height = tcx.basin.right_node->point->y - node.point->y;
+  }
+
+  // if shallow stop filling
+  if (tcx.basin.width > height) {
+    return true;
+  }
+  return false;
+}
+
+void Sweep::FillEdgeEvent(SweepContext& tcx, Edge* edge, Node* node)
+{
+  if (tcx.edge_event.right) {
+    FillRightAboveEdgeEvent(tcx, edge, node);
+  } else {
+    FillLeftAboveEdgeEvent(tcx, edge, node);
+  }
+}
+
+void Sweep::FillRightAboveEdgeEvent(SweepContext& tcx, Edge* edge, Node* node)
+{
+  while (node->next->point->x < edge->p->x) {
+    // Check if next node is below the edge
+    if (Orient2d(*edge->q, *node->next->point, *edge->p) == CCW) {
+      FillRightBelowEdgeEvent(tcx, edge, *node);
+    } else {
+      node = node->next;
+    }
+  }
+}
+
+void Sweep::FillRightBelowEdgeEvent(SweepContext& tcx, Edge* edge, Node& node)
+{
+  if (node.point->x < edge->p->x) {
+    if (Orient2d(*node.point, *node.next->point, *node.next->next->point) == CCW) {
+      // Concave
+      FillRightConcaveEdgeEvent(tcx, edge, node);
+    } else{
+      // Convex
+      FillRightConvexEdgeEvent(tcx, edge, node);
+      // Retry this one
+      FillRightBelowEdgeEvent(tcx, edge, node);
+    }
+  }
+}
+
+void Sweep::FillRightConcaveEdgeEvent(SweepContext& tcx, Edge* edge, Node& node)
+{
+  Fill(tcx, *node.next);
+  if (node.next->point != edge->p) {
+    // Next above or below edge?
+    if (Orient2d(*edge->q, *node.next->point, *edge->p) == CCW) {
+      // Below
+      if (Orient2d(*node.point, *node.next->point, *node.next->next->point) == CCW) {
+        // Next is concave
+        FillRightConcaveEdgeEvent(tcx, edge, node);
+      } else {
+        // Next is convex
+      }
+    }
+  }
+
+}
+
+void Sweep::FillRightConvexEdgeEvent(SweepContext& tcx, Edge* edge, Node& node)
+{
+  // Next concave or convex?
+  if (Orient2d(*node.next->point, *node.next->next->point, *node.next->next->next->point) == CCW) {
+    // Concave
+    FillRightConcaveEdgeEvent(tcx, edge, *node.next);
+  } else{
+    // Convex
+    // Next above or below edge?
+    if (Orient2d(*edge->q, *node.next->next->point, *edge->p) == CCW) {
+      // Below
+      FillRightConvexEdgeEvent(tcx, edge, *node.next);
+    } else{
+      // Above
+    }
+  }
+}
+
+void Sweep::FillLeftAboveEdgeEvent(SweepContext& tcx, Edge* edge, Node* node)
+{
+  while (node->prev->point->x > edge->p->x) {
+    // Check if next node is below the edge
+    if (Orient2d(*edge->q, *node->prev->point, *edge->p) == CW) {
+      FillLeftBelowEdgeEvent(tcx, edge, *node);
+    } else {
+      node = node->prev;
+    }
+  }
+}
+
+void Sweep::FillLeftBelowEdgeEvent(SweepContext& tcx, Edge* edge, Node& node)
+{
+  if (node.point->x > edge->p->x) {
+    if (Orient2d(*node.point, *node.prev->point, *node.prev->prev->point) == CW) {
+      // Concave
+      FillLeftConcaveEdgeEvent(tcx, edge, node);
+    } else {
+      // Convex
+      FillLeftConvexEdgeEvent(tcx, edge, node);
+      // Retry this one
+      FillLeftBelowEdgeEvent(tcx, edge, node);
+    }
+  }
+}
+
+void Sweep::FillLeftConvexEdgeEvent(SweepContext& tcx, Edge* edge, Node& node)
+{
+  // Next concave or convex?
+  if (Orient2d(*node.prev->point, *node.prev->prev->point, *node.prev->prev->prev->point) == CW) {
+    // Concave
+    FillLeftConcaveEdgeEvent(tcx, edge, *node.prev);
+  } else{
+    // Convex
+    // Next above or below edge?
+    if (Orient2d(*edge->q, *node.prev->prev->point, *edge->p) == CW) {
+      // Below
+      FillLeftConvexEdgeEvent(tcx, edge, *node.prev);
+    } else{
+      // Above
+    }
+  }
+}
+
+void Sweep::FillLeftConcaveEdgeEvent(SweepContext& tcx, Edge* edge, Node& node)
+{
+  Fill(tcx, *node.prev);
+  if (node.prev->point != edge->p) {
+    // Next above or below edge?
+    if (Orient2d(*edge->q, *node.prev->point, *edge->p) == CW) {
+      // Below
+      if (Orient2d(*node.point, *node.prev->point, *node.prev->prev->point) == CW) {
+        // Next is concave
+        FillLeftConcaveEdgeEvent(tcx, edge, node);
+      } else{
+        // Next is convex
+      }
+    }
+  }
+
+}
+
+void Sweep::FlipEdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle* t, Point& p)
+{
+  Triangle& ot = t->NeighborAcross(p);
+  Point& op = *ot.OppositePoint(*t, p);
+
+  if (InScanArea(p, *t->PointCCW(p), *t->PointCW(p), op)) {
+    // Lets rotate shared edge one vertex CW
+    RotateTrianglePair(*t, p, ot, op);
+    tcx.MapTriangleToNodes(*t);
+    tcx.MapTriangleToNodes(ot);
+
+    if (p == eq && op == ep) {
+      if (eq == *tcx.edge_event.constrained_edge->q && ep == *tcx.edge_event.constrained_edge->p) {
+        t->MarkConstrainedEdge(&ep, &eq);
+        ot.MarkConstrainedEdge(&ep, &eq);
+        Legalize(tcx, *t);
+        Legalize(tcx, ot);
+      } else {
+        // XXX: I think one of the triangles should be legalized here?
+      }
+    } else {
+      Orientation o = Orient2d(eq, op, ep);
+      t = &NextFlipTriangle(tcx, (int)o, *t, ot, p, op);
+      FlipEdgeEvent(tcx, ep, eq, t, p);
+    }
+  } else {
+    Point& newP = NextFlipPoint(ep, eq, ot, op);
+    FlipScanEdgeEvent(tcx, ep, eq, *t, ot, newP);
+    EdgeEvent(tcx, ep, eq, t, p);
+  }
+}
+
+Triangle& Sweep::NextFlipTriangle(SweepContext& tcx, int o, Triangle& t, Triangle& ot, Point& p, Point& op)
+{
+  if (o == CCW) {
+    // ot is not crossing edge after flip
+    int edge_index = ot.EdgeIndex(&p, &op);
+    ot.delaunay_edge[edge_index] = true;
+    Legalize(tcx, ot);
+    ot.ClearDelunayEdges();
+    return t;
+  }
+
+  // t is not crossing edge after flip
+  int edge_index = t.EdgeIndex(&p, &op);
+
+  t.delaunay_edge[edge_index] = true;
+  Legalize(tcx, t);
+  t.ClearDelunayEdges();
+  return ot;
+}
+
+Point& Sweep::NextFlipPoint(Point& ep, Point& eq, Triangle& ot, Point& op)
+{
+  Orientation o2d = Orient2d(eq, op, ep);
+  if (o2d == CW) {
+    // Right
+    return *ot.PointCCW(op);
+  } else if (o2d == CCW) {
+    // Left
+    return *ot.PointCW(op);
+  } else{
+    //throw new RuntimeException("[Unsupported] Opposing point on constrained edge");
+         // ASSIMP_CHANGE (aramis_acg)
+         throw std::runtime_error("[Unsupported] Opposing point on constrained edge");
+  }
+}
+
+void Sweep::FlipScanEdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle& flip_triangle,
+                              Triangle& t, Point& p)
+{
+  Triangle& ot = t.NeighborAcross(p);
+  Point& op = *ot.OppositePoint(t, p);
+
+  if (InScanArea(eq, *flip_triangle.PointCCW(eq), *flip_triangle.PointCW(eq), op)) {
+    // flip with new edge op->eq
+    FlipEdgeEvent(tcx, eq, op, &ot, op);
+    // TODO: Actually I just figured out that it should be possible to
+    //       improve this by getting the next ot and op before the the above
+    //       flip and continue the flipScanEdgeEvent here
+    // set new ot and op here and loop back to inScanArea test
+    // also need to set a new flip_triangle first
+    // Turns out at first glance that this is somewhat complicated
+    // so it will have to wait.
+  } else{
+    Point& newP = NextFlipPoint(ep, eq, ot, op);
+    FlipScanEdgeEvent(tcx, ep, eq, flip_triangle, ot, newP);
+  }
+}
+
+Sweep::~Sweep() {
+
+    // Clean up memory
+    for(unsigned int i = 0; i < nodes_.size(); i++) {
+        delete nodes_[i];
+    }
+
+}
+
+}
+
index 58c4f28..f45d945 100644 (file)
@@ -1780,8 +1780,8 @@ vn -0.7573840022087097 0.2233279943466187 -0.6135900020599365
 vn -0.902417004108429 0.4006629884243011 -0.1584679931402206
 vn -0.902417004108429 -0.2050659954547882 -0.3789339959621429
 
-# Mesh 'HLeib01_HLeib01_HLeib01_HLeib01_HLeib01_HLeib01_HLeib01_HLeib01' with 80 faces
-g HLeib01_HLeib01_HLeib01_HLeib01_HLeib01_HLeib01_HLeib01_HLeib01
+# Mesh 'HLeib01_HLeib01_HLeib01_HLeib01_HLeib01_HLeib01_HLeib01_HLeib01_HLeib01_HLeib01_HLeib01_HLeib01_HLeib01_HLeib01_HLeib01_HLeib01' with 80 faces
+g HLeib01_HLeib01_HLeib01_HLeib01_HLeib01_HLeib01_HLeib01_HLeib01_HLeib01_HLeib01_HLeib01_HLeib01_HLeib01_HLeib01_HLeib01_HLeib01
 usemtl HLeibTex
 f  1/1/1 2/2/2 3/3/3
 f  4/4/4 3/3/3 5/5/5
@@ -1864,8 +1864,8 @@ f  25/25/25 27/27/27 42/42/42
 f  35/35/35 42/42/42 34/34/34
 f  27/27/27 34/34/34 42/42/42
 
-# Mesh 'OK_OK_OK_OK_OK_OK_OK_OK' with 60 faces
-g OK_OK_OK_OK_OK_OK_OK_OK
+# Mesh 'OK_OK_OK_OK_OK_OK_OK_OK_OK_OK_OK_OK_OK_OK_OK_OK' with 60 faces
+g OK_OK_OK_OK_OK_OK_OK_OK_OK_OK_OK_OK_OK_OK_OK_OK
 usemtl Skin
 f  43/43/43 44/44/44 45/45/45
 f  46/46/46 45/45/45 47/47/47
@@ -1928,8 +1928,8 @@ f  53/53/53 66/63/66 52/52/52
 f  78/67/78 52/52/52 66/63/66
 f  67/64/67 69/63/69 79/67/79
 
-# Mesh 'Bein1Li_Bein1Li_Bein1Li_Bein1Li_Bein1Li_Bein1Li_Bein1Li_Bein1Li' with 98 faces
-g Bein1Li_Bein1Li_Bein1Li_Bein1Li_Bein1Li_Bein1Li_Bein1Li_Bein1Li
+# Mesh 'Bein1Li_Bein1Li_Bein1Li_Bein1Li_Bein1Li_Bein1Li_Bein1Li_Bein1Li_Bein1Li_Bein1Li_Bein1Li_Bein1Li_Bein1Li_Bein1Li_Bein1Li_Bein1Li' with 98 faces
+g Bein1Li_Bein1Li_Bein1Li_Bein1Li_Bein1Li_Bein1Li_Bein1Li_Bein1Li_Bein1Li_Bein1Li_Bein1Li_Bein1Li_Bein1Li_Bein1Li_Bein1Li_Bein1Li
 usemtl BeinTex
 f  80/68/80 81/68/80 82/68/80
 f  83/68/81 84/68/81 85/68/81
@@ -2030,8 +2030,8 @@ f  129/114/128 94/122/92 92/121/90
 f  130/115/129 125/116/130 94/122/92
 f  125/116/130 83/123/94 94/122/92
 
-# Mesh 'Bein1Re_Bein1Re_Bein1Re_Bein1Re_Bein1Re_Bein1Re_Bein1Re_Bein1Re' with 98 faces
-g Bein1Re_Bein1Re_Bein1Re_Bein1Re_Bein1Re_Bein1Re_Bein1Re_Bein1Re
+# Mesh 'Bein1Re_Bein1Re_Bein1Re_Bein1Re_Bein1Re_Bein1Re_Bein1Re_Bein1Re_Bein1Re_Bein1Re_Bein1Re_Bein1Re_Bein1Re_Bein1Re_Bein1Re_Bein1Re' with 98 faces
+g Bein1Re_Bein1Re_Bein1Re_Bein1Re_Bein1Re_Bein1Re_Bein1Re_Bein1Re_Bein1Re_Bein1Re_Bein1Re_Bein1Re_Bein1Re_Bein1Re_Bein1Re_Bein1Re
 usemtl BeinTex
 f  131/68/131 132/68/131 133/68/131
 f  134/68/132 135/68/132 136/68/132
@@ -2132,8 +2132,8 @@ f  143/121/141 146/122/144 180/114/179
 f  146/122/144 176/116/181 181/115/180
 f  146/122/144 136/123/145 176/116/181
 
-# Mesh 'Bein2Li_Bein2Li_Bein2Li_Bein2Li_Bein2Li_Bein2Li_Bein2Li_Bein2Li' with 98 faces
-g Bein2Li_Bein2Li_Bein2Li_Bein2Li_Bein2Li_Bein2Li_Bein2Li_Bein2Li
+# Mesh 'Bein2Li_Bein2Li_Bein2Li_Bein2Li_Bein2Li_Bein2Li_Bein2Li_Bein2Li_Bein2Li_Bein2Li_Bein2Li_Bein2Li_Bein2Li_Bein2Li_Bein2Li_Bein2Li' with 98 faces
+g Bein2Li_Bein2Li_Bein2Li_Bein2Li_Bein2Li_Bein2Li_Bein2Li_Bein2Li_Bein2Li_Bein2Li_Bein2Li_Bein2Li_Bein2Li_Bein2Li_Bein2Li_Bein2Li
 usemtl BeinTex
 f  182/68/182 183/68/182 184/68/182
 f  185/68/183 186/68/183 187/68/183
@@ -2234,8 +2234,8 @@ f  231/114/230 196/122/194 194/121/192
 f  232/115/231 227/116/232 196/122/194
 f  227/116/232 185/123/196 196/122/194
 
-# Mesh 'Bein2Re_Bein2Re_Bein2Re_Bein2Re_Bein2Re_Bein2Re_Bein2Re_Bein2Re' with 98 faces
-g Bein2Re_Bein2Re_Bein2Re_Bein2Re_Bein2Re_Bein2Re_Bein2Re_Bein2Re
+# Mesh 'Bein2Re_Bein2Re_Bein2Re_Bein2Re_Bein2Re_Bein2Re_Bein2Re_Bein2Re_Bein2Re_Bein2Re_Bein2Re_Bein2Re_Bein2Re_Bein2Re_Bein2Re_Bein2Re' with 98 faces
+g Bein2Re_Bein2Re_Bein2Re_Bein2Re_Bein2Re_Bein2Re_Bein2Re_Bein2Re_Bein2Re_Bein2Re_Bein2Re_Bein2Re_Bein2Re_Bein2Re_Bein2Re_Bein2Re
 usemtl BeinTex
 f  233/68/233 234/68/233 235/68/233
 f  236/68/234 237/68/234 238/68/234
@@ -2336,8 +2336,8 @@ f  245/121/243 248/122/246 282/114/281
 f  248/122/246 278/116/283 283/115/282
 f  248/122/246 238/123/247 278/116/283
 
-# Mesh 'Bein3Re_Bein3Re_Bein3Re_Bein3Re_Bein3Re_Bein3Re_Bein3Re_Bein3Re' with 98 faces
-g Bein3Re_Bein3Re_Bein3Re_Bein3Re_Bein3Re_Bein3Re_Bein3Re_Bein3Re
+# Mesh 'Bein3Re_Bein3Re_Bein3Re_Bein3Re_Bein3Re_Bein3Re_Bein3Re_Bein3Re_Bein3Re_Bein3Re_Bein3Re_Bein3Re_Bein3Re_Bein3Re_Bein3Re_Bein3Re' with 98 faces
+g Bein3Re_Bein3Re_Bein3Re_Bein3Re_Bein3Re_Bein3Re_Bein3Re_Bein3Re_Bein3Re_Bein3Re_Bein3Re_Bein3Re_Bein3Re_Bein3Re_Bein3Re_Bein3Re
 usemtl BeinTex
 f  284/68/284 285/68/284 286/68/284
 f  287/68/285 288/68/285 289/68/285
@@ -2438,8 +2438,8 @@ f  296/121/294 299/122/297 333/114/332
 f  299/122/297 329/116/334 334/115/333
 f  299/122/297 289/123/298 329/116/334
 
-# Mesh 'Bein3Li_Bein3Li_Bein3Li_Bein3Li_Bein3Li_Bein3Li_Bein3Li_Bein3Li' with 98 faces
-g Bein3Li_Bein3Li_Bein3Li_Bein3Li_Bein3Li_Bein3Li_Bein3Li_Bein3Li
+# Mesh 'Bein3Li_Bein3Li_Bein3Li_Bein3Li_Bein3Li_Bein3Li_Bein3Li_Bein3Li_Bein3Li_Bein3Li_Bein3Li_Bein3Li_Bein3Li_Bein3Li_Bein3Li_Bein3Li' with 98 faces
+g Bein3Li_Bein3Li_Bein3Li_Bein3Li_Bein3Li_Bein3Li_Bein3Li_Bein3Li_Bein3Li_Bein3Li_Bein3Li_Bein3Li_Bein3Li_Bein3Li_Bein3Li_Bein3Li
 usemtl BeinTex
 f  335/68/335 336/68/335 337/68/335
 f  338/68/336 339/68/336 340/68/336
@@ -2540,8 +2540,8 @@ f  384/114/383 349/122/347 347/121/345
 f  385/115/384 380/116/385 349/122/347
 f  380/116/385 338/123/349 349/122/347
 
-# Mesh 'Bein4Re_Bein4Re_Bein4Re_Bein4Re_Bein4Re_Bein4Re_Bein4Re_Bein4Re' with 98 faces
-g Bein4Re_Bein4Re_Bein4Re_Bein4Re_Bein4Re_Bein4Re_Bein4Re_Bein4Re
+# Mesh 'Bein4Re_Bein4Re_Bein4Re_Bein4Re_Bein4Re_Bein4Re_Bein4Re_Bein4Re_Bein4Re_Bein4Re_Bein4Re_Bein4Re_Bein4Re_Bein4Re_Bein4Re_Bein4Re' with 98 faces
+g Bein4Re_Bein4Re_Bein4Re_Bein4Re_Bein4Re_Bein4Re_Bein4Re_Bein4Re_Bein4Re_Bein4Re_Bein4Re_Bein4Re_Bein4Re_Bein4Re_Bein4Re_Bein4Re
 usemtl BeinTex
 f  386/68/386 387/68/386 388/68/386
 f  389/68/387 390/68/387 391/68/387
@@ -2642,8 +2642,8 @@ f  398/121/396 401/122/399 435/114/434
 f  401/122/399 431/116/436 436/115/435
 f  401/122/399 391/123/400 431/116/436
 
-# Mesh 'Bein4Li_Bein4Li_Bein4Li_Bein4Li_Bein4Li_Bein4Li_Bein4Li_Bein4Li' with 98 faces
-g Bein4Li_Bein4Li_Bein4Li_Bein4Li_Bein4Li_Bein4Li_Bein4Li_Bein4Li
+# Mesh 'Bein4Li_Bein4Li_Bein4Li_Bein4Li_Bein4Li_Bein4Li_Bein4Li_Bein4Li_Bein4Li_Bein4Li_Bein4Li_Bein4Li_Bein4Li_Bein4Li_Bein4Li_Bein4Li' with 98 faces
+g Bein4Li_Bein4Li_Bein4Li_Bein4Li_Bein4Li_Bein4Li_Bein4Li_Bein4Li_Bein4Li_Bein4Li_Bein4Li_Bein4Li_Bein4Li_Bein4Li_Bein4Li_Bein4Li
 usemtl BeinTex
 f  437/68/437 438/68/437 439/68/437
 f  440/68/438 441/68/438 442/68/438
@@ -2744,8 +2744,8 @@ f  486/114/485 451/122/449 449/121/447
 f  487/115/486 482/116/487 451/122/449
 f  482/116/487 440/123/451 451/122/449
 
-# Mesh 'Zahn_Zahn_Zahn_Zahn_Zahn_Zahn_Zahn_Zahn' with 42 faces
-g Zahn_Zahn_Zahn_Zahn_Zahn_Zahn_Zahn_Zahn
+# Mesh 'Zahn_Zahn_Zahn_Zahn_Zahn_Zahn_Zahn_Zahn_Zahn_Zahn_Zahn_Zahn_Zahn_Zahn_Zahn_Zahn' with 42 faces
+g Zahn_Zahn_Zahn_Zahn_Zahn_Zahn_Zahn_Zahn_Zahn_Zahn_Zahn_Zahn_Zahn_Zahn_Zahn_Zahn
 usemtl BeinTex
 f  488/124/488 488/124/488 488/124/488
 f  489/125/489 490/126/489 491/127/489
@@ -2790,8 +2790,8 @@ f  488/124/505 492/128/491 488/124/490
 f  503/139/506 502/138/507 492/128/491
 f  502/138/507 489/125/493 492/128/491
 
-# Mesh 'klZahn_klZahn_klZahn_klZahn_klZahn_klZahn_klZahn_klZahn' with 42 faces
-g klZahn_klZahn_klZahn_klZahn_klZahn_klZahn_klZahn_klZahn
+# Mesh 'klZahn_klZahn_klZahn_klZahn_klZahn_klZahn_klZahn_klZahn_klZahn_klZahn_klZahn_klZahn_klZahn_klZahn_klZahn_klZahn' with 42 faces
+g klZahn_klZahn_klZahn_klZahn_klZahn_klZahn_klZahn_klZahn_klZahn_klZahn_klZahn_klZahn_klZahn_klZahn_klZahn_klZahn
 usemtl BeinTex
 f  504/140/488 504/140/488 504/140/488
 f  505/141/508 506/142/508 507/143/508
@@ -2836,8 +2836,8 @@ f  504/140/524 508/144/510 504/140/509
 f  519/155/525 518/154/526 508/144/510
 f  518/154/526 505/141/512 508/144/510
 
-# Mesh 'Kopf_Kopf_Kopf_Kopf_Kopf_Kopf_Kopf_Kopf' with 90 faces
-g Kopf_Kopf_Kopf_Kopf_Kopf_Kopf_Kopf_Kopf
+# Mesh 'Kopf_Kopf_Kopf_Kopf_Kopf_Kopf_Kopf_Kopf_Kopf_Kopf_Kopf_Kopf_Kopf_Kopf_Kopf_Kopf' with 90 faces
+g Kopf_Kopf_Kopf_Kopf_Kopf_Kopf_Kopf_Kopf_Kopf_Kopf_Kopf_Kopf_Kopf_Kopf_Kopf_Kopf
 usemtl Skin
 f  520/68/527 521/156/528 522/157/529
 f  520/68/527 523/158/530 521/156/528
@@ -2930,8 +2930,8 @@ f  564/197/571 562/195/569 545/178/552
 f  545/178/552 552/185/559 566/199/573
 f  564/197/571 566/199/573 545/178/552
 
-# Mesh 'Brust_Brust_Brust_Brust_Brust_Brust_Brust_Brust' with 20 faces
-g Brust_Brust_Brust_Brust_Brust_Brust_Brust_Brust
+# Mesh 'Brust_Brust_Brust_Brust_Brust_Brust_Brust_Brust_Brust_Brust_Brust_Brust_Brust_Brust_Brust_Brust' with 20 faces
+g Brust_Brust_Brust_Brust_Brust_Brust_Brust_Brust_Brust_Brust_Brust_Brust_Brust_Brust_Brust_Brust
 usemtl Skin
 f  70/210/584 71/211/585 577/212/586
 f  60/120/587 577/212/586 64/213/588
@@ -2954,8 +2954,8 @@ f  70/210/584 580/217/592 69/223/599
 f  77/75/593 79/224/600 580/217/592
 f  69/223/599 580/217/592 79/224/600
 
-# Mesh 'Kopf2_Kopf2_Kopf2_Kopf2_Kopf2_Kopf2_Kopf2_Kopf2' with 90 faces
-g Kopf2_Kopf2_Kopf2_Kopf2_Kopf2_Kopf2_Kopf2_Kopf2
+# Mesh 'Kopf2_Kopf2_Kopf2_Kopf2_Kopf2_Kopf2_Kopf2_Kopf2_Kopf2_Kopf2_Kopf2_Kopf2_Kopf2_Kopf2_Kopf2_Kopf2' with 90 faces
+g Kopf2_Kopf2_Kopf2_Kopf2_Kopf2_Kopf2_Kopf2_Kopf2_Kopf2_Kopf2_Kopf2_Kopf2_Kopf2_Kopf2_Kopf2_Kopf2
 usemtl Skin
 f  582/225/601 583/226/602 584/123/603
 f  583/226/602 585/227/604 584/123/603
@@ -3048,8 +3048,8 @@ f  607/245/626 624/262/643 625/263/644
 f  627/265/646 614/252/633 607/245/626
 f  607/245/626 627/265/646 625/263/644
 
-# Mesh 'Zahn2_Zahn2_Zahn2_Zahn2_Zahn2_Zahn2_Zahn2_Zahn2' with 42 faces
-g Zahn2_Zahn2_Zahn2_Zahn2_Zahn2_Zahn2_Zahn2_Zahn2
+# Mesh 'Zahn2_Zahn2_Zahn2_Zahn2_Zahn2_Zahn2_Zahn2_Zahn2_Zahn2_Zahn2_Zahn2_Zahn2_Zahn2_Zahn2_Zahn2_Zahn2' with 42 faces
+g Zahn2_Zahn2_Zahn2_Zahn2_Zahn2_Zahn2_Zahn2_Zahn2_Zahn2_Zahn2_Zahn2_Zahn2_Zahn2_Zahn2_Zahn2_Zahn2
 usemtl BeinTex
 f  639/124/488 639/124/488 639/124/488
 f  640/127/658 641/126/658 642/125/658
@@ -3094,8 +3094,8 @@ f  639/124/661 644/128/660 639/124/674
 f  644/128/660 653/138/676 654/139/675
 f  644/128/660 642/125/662 653/138/676
 
-# Mesh 'klZahn2_klZahn2_klZahn2_klZahn2_klZahn2_klZahn2_klZahn2_klZahn2' with 42 faces
-g klZahn2_klZahn2_klZahn2_klZahn2_klZahn2_klZahn2_klZahn2_klZahn2
+# Mesh 'klZahn2_klZahn2_klZahn2_klZahn2_klZahn2_klZahn2_klZahn2_klZahn2_klZahn2_klZahn2_klZahn2_klZahn2_klZahn2_klZahn2_klZahn2_klZahn2' with 42 faces
+g klZahn2_klZahn2_klZahn2_klZahn2_klZahn2_klZahn2_klZahn2_klZahn2_klZahn2_klZahn2_klZahn2_klZahn2_klZahn2_klZahn2_klZahn2_klZahn2
 usemtl BeinTex
 f  655/140/488 655/140/488 655/140/488
 f  656/143/677 657/142/677 658/141/677
@@ -3140,8 +3140,8 @@ f  655/140/680 660/144/679 655/140/693
 f  660/144/679 669/154/695 670/155/694
 f  660/144/679 658/141/681 669/154/695
 
-# Mesh 'Auge_Auge_Auge_Auge_Auge_Auge_Auge_Auge' with 38 faces
-g Auge_Auge_Auge_Auge_Auge_Auge_Auge_Auge
+# Mesh 'Auge_Auge_Auge_Auge_Auge_Auge_Auge_Auge_Auge_Auge_Auge_Auge_Auge_Auge_Auge_Auge' with 38 faces
+g Auge_Auge_Auge_Auge_Auge_Auge_Auge_Auge_Auge_Auge_Auge_Auge_Auge_Auge_Auge_Auge
 usemtl Augentex
 f  671/277/696 672/278/697 673/279/698
 f  671/277/696 673/279/698 674/280/699
@@ -3182,8 +3182,8 @@ f  681/287/706 684/290/709 696/302/721
 f  689/295/714 696/302/721 688/294/713
 f  684/290/709 688/294/713 696/302/721
 
-# Mesh 'Duplicate05_Duplicate05_Duplicate05_Duplicate05_Duplicate05_Duplicate05_Duplicate05_Duplicate05' with 38 faces
-g Duplicate05_Duplicate05_Duplicate05_Duplicate05_Duplicate05_Duplicate05_Duplicate05_Duplicate05
+# Mesh 'Duplicate05_Duplicate05_Duplicate05_Duplicate05_Duplicate05_Duplicate05_Duplicate05_Duplicate05_Duplicate05_Duplicate05_Duplicate05_Duplicate05_Duplicate05_Duplicate05_Duplicate05_Duplicate05' with 38 faces
+g Duplicate05_Duplicate05_Duplicate05_Duplicate05_Duplicate05_Duplicate05_Duplicate05_Duplicate05_Duplicate05_Duplicate05_Duplicate05_Duplicate05_Duplicate05_Duplicate05_Duplicate05_Duplicate05
 usemtl Augentex
 f  697/279/722 698/278/723 699/277/724
 f  700/280/725 697/279/722 699/277/724