diff options
author | Miika Hamalainen <blender@miikah.org> | 2012-08-06 13:20:12 +0400 |
---|---|---|
committer | Miika Hamalainen <blender@miikah.org> | 2012-08-06 13:20:12 +0400 |
commit | b4d7f7c49646c52a325242a649b72df16e8223f7 (patch) | |
tree | dbd98ff838cb41a64966e3db8f8e104797f93242 /intern | |
parent | 61111325f17537dc9c475678e63c11f1057852f0 (diff) | |
parent | 3b743582ec282cfffc84c5e235f58fe2745327c9 (diff) |
Merge with trunk r49600
Diffstat (limited to 'intern')
108 files changed, 790 insertions, 14912 deletions
diff --git a/intern/CMakeLists.txt b/intern/CMakeLists.txt index 71d2ef5e410..2b4a84d6b39 100644 --- a/intern/CMakeLists.txt +++ b/intern/CMakeLists.txt @@ -55,7 +55,6 @@ if(WITH_MOD_DECIMATE) endif() if(WITH_MOD_BOOLEAN) - add_subdirectory(boolop) add_subdirectory(bsp) endif() diff --git a/intern/SConscript b/intern/SConscript index 3bfdc2c4ca7..53fc80b0317 100644 --- a/intern/SConscript +++ b/intern/SConscript @@ -11,7 +11,6 @@ SConscript(['audaspace/SConscript', 'decimation/SConscript', 'iksolver/SConscript', 'itasc/SConscript', - 'boolop/SConscript', 'opennl/SConscript', 'mikktspace/SConscript', 'smoke/SConscript', @@ -26,7 +25,8 @@ if env['WITH_BF_FLUID']: if env['WITH_BF_CYCLES']: SConscript(['cycles/SConscript']) -SConscript(['bsp/SConscript']) +if env['WITH_BF_BOOLEAN']: + SConscript(['bsp/SConscript']) if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'win64-mingw', 'linuxcross', 'win64-vc'): SConscript(['utfconv/SConscript']) diff --git a/intern/audaspace/FX/AUD_ButterworthFactory.h b/intern/audaspace/FX/AUD_ButterworthFactory.h index d3606270154..dc8b4d92775 100644 --- a/intern/audaspace/FX/AUD_ButterworthFactory.h +++ b/intern/audaspace/FX/AUD_ButterworthFactory.h @@ -56,8 +56,8 @@ public: AUD_ButterworthFactory(AUD_Reference<AUD_IFactory> factory, float frequency); virtual void recalculateCoefficients(AUD_SampleRate rate, - std::vector<float>& b, - std::vector<float>& a); + std::vector<float>& b, + std::vector<float>& a); }; #endif //__AUD_BUTTERWORTHFACTORY_H__ diff --git a/intern/audaspace/FX/AUD_DynamicIIRFilterFactory.h b/intern/audaspace/FX/AUD_DynamicIIRFilterFactory.h index fef379f68b1..5b297db2d56 100644 --- a/intern/audaspace/FX/AUD_DynamicIIRFilterFactory.h +++ b/intern/audaspace/FX/AUD_DynamicIIRFilterFactory.h @@ -56,8 +56,8 @@ public: * \param[out] a The output filter coefficients. */ virtual void recalculateCoefficients(AUD_SampleRate rate, - std::vector<float>& b, - std::vector<float>& a)=0; + std::vector<float>& b, + std::vector<float>& a)=0; }; #endif // __AUD_DYNAMICIIRFILTERFACTORY_H__ diff --git a/intern/audaspace/FX/AUD_FaderFactory.h b/intern/audaspace/FX/AUD_FaderFactory.h index 8fcd4baa623..82eaf2fae9f 100644 --- a/intern/audaspace/FX/AUD_FaderFactory.h +++ b/intern/audaspace/FX/AUD_FaderFactory.h @@ -68,8 +68,8 @@ public: * \param length How long fading should last in seconds. */ AUD_FaderFactory(AUD_Reference<AUD_IFactory> factory, - AUD_FadeType type = AUD_FADE_IN, - float start = 0.0f, float length = 1.0f); + AUD_FadeType type = AUD_FADE_IN, + float start = 0.0f, float length = 1.0f); /** * Returns the fading type. diff --git a/intern/audaspace/intern/AUD_3DMath.h b/intern/audaspace/intern/AUD_3DMath.h index f39566958cd..1b109ebee1e 100644 --- a/intern/audaspace/intern/AUD_3DMath.h +++ b/intern/audaspace/intern/AUD_3DMath.h @@ -136,8 +136,8 @@ public: inline AUD_Vector3 cross(const AUD_Vector3& op) const { return AUD_Vector3(m_y * op.m_z - m_z * op.m_y, - m_z * op.m_x - m_x * op.m_z, - m_x * op.m_y - m_y * op.m_x); + m_z * op.m_x - m_x * op.m_z, + m_x * op.m_y - m_y * op.m_x); } /** diff --git a/intern/audaspace/intern/AUD_C-API.h b/intern/audaspace/intern/AUD_C-API.h index 66e6984c71b..6af0c648d0e 100644 --- a/intern/audaspace/intern/AUD_C-API.h +++ b/intern/audaspace/intern/AUD_C-API.h @@ -442,10 +442,10 @@ extern void AUD_closeReadDevice(AUD_Device* device); * The sound is therefore bandpassed, rectified and resampled. */ extern float* AUD_readSoundBuffer(const char* filename, float low, float high, - float attack, float release, float threshold, - int accumulate, int additive, int square, - float sthreshold, double samplerate, - int* length); + float attack, float release, float threshold, + int accumulate, int additive, int square, + float sthreshold, double samplerate, + int* length); /** * Pauses a playing sound after a specific amount of time. @@ -493,7 +493,7 @@ extern void AUD_setSequencerFPS(AUD_Sound* sequencer, float fps); * \return The entry added. */ extern AUD_SEntry* AUD_addSequence(AUD_Sound* sequencer, AUD_Sound* sound, - float begin, float end, float skip); + float begin, float end, float skip); /** * Removes an entry from the scene. @@ -567,8 +567,8 @@ extern void AUD_setSequencerAnimData(AUD_Sound* sequencer, AUD_AnimateableProper * \param cone_volume_outer The volume outside the outer cone. */ extern void AUD_updateSequenceData(AUD_SEntry* entry, float volume_max, float volume_min, - float distance_max, float distance_reference, float attenuation, - float cone_angle_outer, float cone_angle_inner, float cone_volume_outer); + float distance_max, float distance_reference, float attenuation, + float cone_angle_outer, float cone_angle_inner, float cone_volume_outer); /** * Updates all non-animated parameters of the entry. @@ -578,7 +578,7 @@ extern void AUD_updateSequenceData(AUD_SEntry* entry, float volume_max, float vo * \param model The distance model for distance calculation. */ extern void AUD_updateSequencerData(AUD_Sound* sequencer, float speed_of_sound, - float factor, AUD_DistanceModel model); + float factor, AUD_DistanceModel model); /** * Sets the audio output specification of the sound scene to the specs of the diff --git a/intern/boolop/CMakeLists.txt b/intern/boolop/CMakeLists.txt deleted file mode 100644 index d8e9c0c94d7..00000000000 --- a/intern/boolop/CMakeLists.txt +++ /dev/null @@ -1,111 +0,0 @@ -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# The Original Code is Copyright (C) 2006, Blender Foundation -# All rights reserved. -# -# The Original Code is: all of this file. -# -# Contributor(s): Jacques Beaurain. -# -# ***** END GPL LICENSE BLOCK ***** - -remove_strict_flags() - -set(INC - . - extern - intern - ../container - ../guardedalloc - ../memutil - ../moto/include - ../../source/blender/blenlib - ../../source/blender/makesdna -) - -set(INC_SYS - -) - -if(NOT WITH_CARVE) - set(SRC - intern/BOP_BBox.cpp - intern/BOP_BSPNode.cpp - intern/BOP_BSPTree.cpp - intern/BOP_Edge.cpp - intern/BOP_Face.cpp - intern/BOP_Face2Face.cpp - intern/BOP_Interface.cpp - intern/BOP_MathUtils.cpp - intern/BOP_Merge.cpp - intern/BOP_Merge2.cpp - intern/BOP_Mesh.cpp - intern/BOP_Segment.cpp - intern/BOP_Splitter.cpp - intern/BOP_Tag.cpp - intern/BOP_Triangulator.cpp - intern/BOP_Vertex.cpp - - extern/BOP_Interface.h - intern/BOP_BBox.h - intern/BOP_BSPNode.h - intern/BOP_BSPTree.h - intern/BOP_Chrono.h - intern/BOP_Edge.h - intern/BOP_Face.h - intern/BOP_Face2Face.h - intern/BOP_Indexs.h - intern/BOP_MathUtils.h - intern/BOP_Merge.h - intern/BOP_Merge2.h - intern/BOP_Mesh.h - intern/BOP_Misc.h - intern/BOP_Segment.h - intern/BOP_Splitter.h - intern/BOP_Tag.h - intern/BOP_Triangulator.h - intern/BOP_Vertex.h - ) -else() - set(SRC - intern/BOP_CarveInterface.cpp - extern/BOP_Interface.h - ) - - list(APPEND INC - ../../extern/carve/include - ) - - if(WITH_BOOST) - if(NOT MSVC) - # Boost is setting as preferred collections library in the Carve code when using MSVC compiler - add_definitions( - -DHAVE_BOOST_UNORDERED_COLLECTIONS - ) - endif() - - add_definitions( - -DCARVE_SYSTEM_BOOST - ) - - list(APPEND INC - ${BOOST_INCLUDE_DIR} - ) - endif() -endif() - -blender_add_lib(bf_intern_bop "${SRC}" "${INC}" "${INC_SYS}") diff --git a/intern/boolop/SConscript b/intern/boolop/SConscript deleted file mode 100644 index f630d1d58e0..00000000000 --- a/intern/boolop/SConscript +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/python -Import ('env') - -incs = '. intern extern ../moto/include ../container ../memutil' -incs += ' ../../source/blender/makesdna ../../intern/guardedalloc' -incs += ' ../../source/blender/blenlib' - -defs = [] - -if not env['WITH_BF_CARVE']: - import os - sources = env.Glob('intern/*.cpp') - sources.remove('intern' + os.sep + 'BOP_CarveInterface.cpp') -else: - sources = env.Glob('intern/BOP_CarveInterface.cpp') - incs += ' ../../extern/carve/include' - - if env['WITH_BF_BOOST']: - if env['OURPLATFORM'] not in ('win32-vc', 'win64-vc'): - # Boost is setting as preferred collections library in the Carve code when using MSVC compiler - if env['OURPLATFORM'] not in ('win32-mingw', 'win64-mingw'): - defs.append('HAVE_BOOST_UNORDERED_COLLECTIONS') - - defs.append('CARVE_SYSTEM_BOOST') - incs += ' ' + env['BF_BOOST_INC'] - -if (env['OURPLATFORM'] in ('win32-mingw', 'win64-mingw')): - env.BlenderLib ('bf_intern_bop', sources, Split(incs) , [], libtype='intern', priority = 5 ) -else: - env.BlenderLib ('bf_intern_bop', sources, Split(incs) , defs, libtype='intern', priority = 5 ) - diff --git a/intern/boolop/intern/BOP_BBox.cpp b/intern/boolop/intern/BOP_BBox.cpp deleted file mode 100644 index a42c7d936cf..00000000000 --- a/intern/boolop/intern/BOP_BBox.cpp +++ /dev/null @@ -1,64 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file boolop/intern/BOP_BBox.cpp - * \ingroup boolopintern - */ - - -#include "BOP_BBox.h" - -#include "MT_Scalar.h" - -/** - * Constructs a nwe bounding box. - */ -BOP_BBox::BOP_BBox() -{ - m_minX = MT_INFINITY; - m_minY = MT_INFINITY; - m_minZ = MT_INFINITY; - m_maxX = -MT_INFINITY; - m_maxY = -MT_INFINITY; - m_maxZ = -MT_INFINITY; -} - -/** - * Constructs a new bounding box using three points. - * @param p1 first point - * @param p2 second point - * @param p3 third point - */ -BOP_BBox::BOP_BBox(const MT_Point3& p1,const MT_Point3& p2,const MT_Point3& p3) -{ - m_minX = BOP_MIN(BOP_MIN(p1[0],p2[0]),p3[0]); - m_minY = BOP_MIN(BOP_MIN(p1[1],p2[1]),p3[1]); - m_minZ = BOP_MIN(BOP_MIN(p1[2],p2[2]),p3[2]); - m_maxX = BOP_MAX(BOP_MAX(p1[0],p2[0]),p3[0]); - m_maxY = BOP_MAX(BOP_MAX(p1[1],p2[1]),p3[1]); - m_maxZ = BOP_MAX(BOP_MAX(p1[2],p2[2]),p3[2]); -} diff --git a/intern/boolop/intern/BOP_BBox.h b/intern/boolop/intern/BOP_BBox.h deleted file mode 100644 index c58bb704fc3..00000000000 --- a/intern/boolop/intern/BOP_BBox.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file boolop/intern/BOP_BBox.h - * \ingroup boolopintern - */ - - -#ifndef __BOP_BBOX_H__ -#define __BOP_BBOX_H__ - -#include "MT_Point3.h" -#include "BOP_MathUtils.h" - -#define BOP_MAX(a, b) ((a > b) ? a : b) -#define BOP_MIN(a, b) ((a < b) ? a : b) -#define BOP_ABS(a) ((a < 0) ? -(a) : a) - -class BOP_BBox -{ -public: - MT_Scalar m_minX; - MT_Scalar m_minY; - MT_Scalar m_minZ; - MT_Scalar m_maxX; - MT_Scalar m_maxY; - MT_Scalar m_maxZ; - MT_Scalar m_centerX; - MT_Scalar m_centerY; - MT_Scalar m_centerZ; - MT_Scalar m_extentX; - MT_Scalar m_extentY; - MT_Scalar m_extentZ; - -public: - BOP_BBox(); - BOP_BBox(const MT_Point3& p1,const MT_Point3& p2,const MT_Point3& p3); - inline void add(const MT_Point3& p) - { - m_minX = BOP_MIN(m_minX,p[0]); - m_minY = BOP_MIN(m_minY,p[1]); - m_minZ = BOP_MIN(m_minZ,p[2]); - m_maxX = BOP_MAX(m_maxX,p[0]); - m_maxY = BOP_MAX(m_maxY,p[1]); - m_maxZ = BOP_MAX(m_maxZ,p[2]); - }; - - inline const MT_Scalar getCenterX() const {return m_centerX;}; - inline const MT_Scalar getCenterY() const {return m_centerY;}; - inline const MT_Scalar getCenterZ() const {return m_centerZ;}; - - inline const MT_Scalar getExtentX() const {return m_extentX;}; - inline const MT_Scalar getExtentY() const {return m_extentY;}; - inline const MT_Scalar getExtentZ() const {return m_extentZ;}; - - inline void compute() { - m_extentX = (m_maxX-m_minX)/2.0f; - m_extentY = (m_maxY-m_minY)/2.0f; - m_extentZ = (m_maxZ-m_minZ)/2.0f; - m_centerX = m_minX+m_extentX; - m_centerY = m_minY+m_extentY; - m_centerZ = m_minZ+m_extentZ; - }; - - inline const bool intersect(const BOP_BBox& b) const { - return (!((BOP_comp(m_maxX,b.m_minX)<0) || (BOP_comp(b.m_maxX,m_minX)<0) || - (BOP_comp(m_maxY,b.m_minY)<0) || (BOP_comp(b.m_maxY,m_minY)<0) || - (BOP_comp(m_maxZ,b.m_minZ)<0) || (BOP_comp(b.m_maxZ,m_minZ)<0))); - }; - - -}; - -#endif diff --git a/intern/boolop/intern/BOP_BSPNode.cpp b/intern/boolop/intern/BOP_BSPNode.cpp deleted file mode 100644 index 3588e80c28e..00000000000 --- a/intern/boolop/intern/BOP_BSPNode.cpp +++ /dev/null @@ -1,718 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file boolop/intern/BOP_BSPNode.cpp - * \ingroup boolopintern - */ - - -#include "BOP_MathUtils.h" -#include "BOP_BSPNode.h" -#include "MT_assert.h" -#include "MT_MinMax.h" -#include <iostream> - -/** - * Constructs a new BSP node. - * @param plane split plane. - */ -BOP_BSPNode::BOP_BSPNode(const MT_Plane3& plane) -{ - m_plane = plane; - m_inChild = NULL; - m_outChild = NULL; - m_deep = 1; -} - -/** - * Destroys a BSP tree. - */ -BOP_BSPNode::~BOP_BSPNode() -{ - if (m_inChild!=NULL) delete m_inChild; - if (m_outChild!=NULL) delete m_outChild; -} - -/** - * Adds a new face to this BSP tree. - * @param pts vector containing face points - * @param plane face plane. - */ - -unsigned int BOP_BSPNode::addFace(const BOP_BSPPoints& pts, - const MT_Plane3& plane ) -{ - unsigned int newDeep = 0; - BOP_TAG tag = ON; - - // find out if any points on the "face" lie in either half-space - BOP_IT_BSPPoints ptsEnd = pts.end(); - for(BOP_IT_BSPPoints itp=pts.begin();itp!=ptsEnd;itp++){ - tag = (BOP_TAG) ((int) tag | (int)testPoint(*itp)); - } - - if (tag == ON) { } // face lies on hyperplane: do nothing - else if ((tag & IN) != 0 && (tag & OUT) == 0) { // face is entirely on inside - if (m_inChild != NULL) - newDeep = m_inChild->addFace(pts, plane) + 1; - else { - m_inChild = new BOP_BSPNode(plane); - newDeep = 2; - } - } else if ((tag & OUT) != 0 && (tag & IN) == 0) { // face is entirely on outside - if (m_outChild != NULL) - newDeep = m_outChild->addFace(pts, plane) + 1; - else { - m_outChild = new BOP_BSPNode(plane); - newDeep = 2; - } - } else { // face lies in both half-spaces: split it - BOP_BSPPoints inside, outside; - MT_Point3 lpoint= pts[pts.size()-1]; - BOP_TAG ltag = testPoint(lpoint); - BOP_TAG tstate = ltag; - - // classify each line segment, looking for endpoints which lie on different - // sides of the hyperplane. - - ptsEnd = pts.end(); - for(BOP_IT_BSPPoints itp=pts.begin();itp!=ptsEnd;itp++){ - MT_Point3 npoint= *itp; - BOP_TAG ntag = testPoint(npoint); - - if(ltag != ON) { // last point not on hyperplane - if(tstate == IN) { - if (m_inChild != NULL) inside.push_back(lpoint); - } else { - if (m_outChild != NULL) outside.push_back(lpoint); - } - if(ntag != ON && ntag != tstate) { // last, self in different half-spaces - MT_Point3 mpoint = BOP_intersectPlane( m_plane, lpoint, npoint ); - if (m_inChild != NULL) inside.push_back(mpoint); - if (m_outChild != NULL) outside.push_back(mpoint); - tstate = ntag; - } - } else { // last point on hyperplane, so we're switching - // half-spaces - // boundary point belong to both faces - if (m_inChild != NULL) inside.push_back(lpoint); - if (m_outChild != NULL) outside.push_back(lpoint); - tstate = ntag; // state changes to new point tag - } - lpoint = npoint; // save point, tag for next iteration - ltag = ntag; - } - - if (m_inChild != NULL) - newDeep = m_inChild->addFace(inside, plane) + 1; - else { - m_inChild = new BOP_BSPNode(plane); - newDeep = 2; - } - if (m_outChild != NULL) - newDeep = MT_max(newDeep, m_outChild->addFace(outside, plane) + 1); - else { - m_outChild = new BOP_BSPNode(plane); - newDeep = MT_max(newDeep,(unsigned int)2); - } - } - - // update the deep attribute - m_deep = MT_max(m_deep,newDeep); - - return m_deep; -} - -/** - * Tests the point situation respect the node plane. - * @param p point to test. - * @return TAG result: IN, OUT or ON. - */ -BOP_TAG BOP_BSPNode::testPoint(const MT_Point3& p) const -{ - return BOP_createTAG(BOP_classify(p,m_plane)); - -} - -/** - * Classifies a face using its coordinates and plane. - * @param p1 first point. - * @param p2 second point. - * @param p3 third point. - * @param plane face plane. - * @return TAG result: IN, OUT or IN&OUT. - */ -BOP_TAG BOP_BSPNode::classifyFace(const MT_Point3& p1, - const MT_Point3& p2, - const MT_Point3& p3, - const MT_Plane3& plane) const -{ - // local variables - MT_Point3 auxp1, auxp2; - BOP_TAG auxtag1, auxtag2, auxtag3; - - switch(BOP_createTAG(testPoint(p1),testPoint(p2),testPoint(p3))) { - // Classify the face on the IN side - case IN_IN_IN : - return classifyFaceIN(p1, p2, p3, plane); - case IN_IN_ON : - case IN_ON_IN : - case ON_IN_IN : - case IN_ON_ON : - case ON_IN_ON : - case ON_ON_IN : - return BOP_addON(classifyFaceIN(p1, p2, p3, plane)); - - // Classify the face on the OUT side - case OUT_OUT_OUT : - return classifyFaceOUT(p1, p2, p3, plane); - case OUT_OUT_ON : - case OUT_ON_OUT : - case ON_OUT_OUT : - case ON_ON_OUT : - case ON_OUT_ON : - case OUT_ON_ON : - return BOP_addON(classifyFaceOUT(p1, p2, p3, plane)); - - // Classify the ON face depending on it plane normal - case ON_ON_ON : - if (hasSameOrientation(plane)) - return BOP_addON(classifyFaceIN(p1, p2, p3, plane)); - else - return BOP_addON(classifyFaceOUT(p1, p2, p3, plane)); - - // Classify the face IN/OUT and one vertex ON - // becouse only one ON, only one way to subdivide the face - case IN_OUT_ON : - auxp1 = BOP_intersectPlane(m_plane, p1, p2); - auxtag1 = classifyFaceIN( p1, auxp1 , p3, plane); - auxtag2 = classifyFaceOUT(auxp1, p2, p3, plane); - return (BOP_compTAG(auxtag1,auxtag2)?BOP_addON(auxtag1):INOUT); - - case OUT_IN_ON : - auxp1 = BOP_intersectPlane(m_plane, p1, p2); - auxtag1 = classifyFaceOUT(p1, auxp1, p3, plane); - auxtag2 = classifyFaceIN( auxp1, p2, p3, plane); - return (BOP_compTAG(auxtag1,auxtag2)?BOP_addON(auxtag1):INOUT); - - case IN_ON_OUT : - auxp1 = BOP_intersectPlane(m_plane, p1, p3); - auxtag1 = classifyFaceIN( p1, p2, auxp1, plane); - auxtag2 = classifyFaceOUT(p2, p3, auxp1, plane); - return (BOP_compTAG(auxtag1,auxtag2)?BOP_addON(auxtag1):INOUT); - - case OUT_ON_IN : - auxp1 = BOP_intersectPlane(m_plane, p1, p3); - auxtag1 = classifyFaceOUT(p1, p2, auxp1, plane); - auxtag2 = classifyFaceIN( p2, p3, auxp1, plane); - return (BOP_compTAG(auxtag1,auxtag2)?BOP_addON(auxtag1):INOUT); - - case ON_IN_OUT : - auxp1 = BOP_intersectPlane(m_plane, p2, p3); - auxtag1 = classifyFaceIN( p1, p2, auxp1, plane); - auxtag2 = classifyFaceOUT(auxp1, p3, p1, plane); - return (BOP_compTAG(auxtag1,auxtag2)?BOP_addON(auxtag1):INOUT); - - case ON_OUT_IN : - auxp1 = BOP_intersectPlane(m_plane, p2, p3); - auxtag1 = classifyFaceOUT(p1, p2, auxp1, plane); - auxtag2 = classifyFaceIN( auxp1, p3, p1, plane); - return (BOP_compTAG(auxtag1,auxtag2)?BOP_addON(auxtag1):INOUT); - - // Classify IN/OUT face without ON vertices. - // Two ways to divide the triangle, - // will chose the least degenerated sub-triangles. - case IN_OUT_OUT : - auxp1 = BOP_intersectPlane(m_plane, p1, p2); - auxp2 = BOP_intersectPlane(m_plane, p1, p3); - - // f1: p1 auxp1 , auxp1 auxp2 - auxtag1 = classifyFaceIN(p1, auxp1, auxp2, plane); - - // f2: auxp1 p2 , p2 auxp2; f3: p2 p3 , p3 auxp2 || - // f2: auxp1 p3, p3 auxp2; f3: p2 p3 , p3 auxp1 - if (BOP_isInsideCircle(p2, p3, auxp1, auxp2)) { - auxtag2 = classifyFaceOUT(auxp1, p2, auxp2, plane); - auxtag3 = classifyFaceOUT(p2, p3, auxp2, plane); - } - else { - auxtag2 = classifyFaceOUT(auxp1, p3, auxp2, plane); - auxtag3 = classifyFaceOUT(p2, p3, auxp1, plane); - } - return (BOP_compTAG(auxtag1,auxtag2)&&BOP_compTAG(auxtag2,auxtag3)?auxtag1:INOUT); - - case OUT_IN_IN : - auxp1 = BOP_intersectPlane(m_plane, p1, p2); - auxp2 = BOP_intersectPlane(m_plane, p1, p3); - - // f1: p1 auxp1 , auxp1 auxp2 - auxtag1 = classifyFaceOUT(p1, auxp1, auxp2, plane); - - // f2: auxp1 p2 , p2 auxp2; f3: p2 p3 , p3 auxp2 || - // f2: auxp1 p3, p3 auxp2; f3: p2 p3 , p3 auxp1 - if (BOP_isInsideCircle(p2, p3, auxp1, auxp2)) { - auxtag2 = classifyFaceIN(auxp1, p2, auxp2, plane); - auxtag3 = classifyFaceIN(p2, p3, auxp2, plane); - } - else { - auxtag2 = classifyFaceIN(auxp1, p3, auxp2, plane); - auxtag3 = classifyFaceIN(p2, p3, auxp1, plane); - } - return (BOP_compTAG(auxtag1,auxtag2)&&BOP_compTAG(auxtag2,auxtag3)?auxtag1:INOUT); - - case OUT_IN_OUT : - auxp1 = BOP_intersectPlane(m_plane, p2, p1); - auxp2 = BOP_intersectPlane(m_plane, p2, p3); - - // f1: auxp1 p2 , p2 auxp2 - auxtag1 = classifyFaceIN(auxp1, p2, auxp2, plane); - - // f2: p1 auxp1 , auxp1 auxp2; f3: p1 auxp2 , auxp2 p3 || - // f2: p3 auxp1, auxp1 auxp2 f3:p1 auxp1, auxp1 p3 - if (BOP_isInsideCircle(p1, p3, auxp1, auxp2)) { - auxtag2 = classifyFaceOUT(p1, auxp1, auxp2, plane); - auxtag3 = classifyFaceOUT(p1, auxp2, p3, plane); - } - else { - auxtag2 = classifyFaceOUT(p3, auxp1, auxp2, plane); - auxtag3 = classifyFaceOUT(p1, auxp1, p3, plane); - } - return (BOP_compTAG(auxtag1,auxtag2)&&BOP_compTAG(auxtag2,auxtag3)?auxtag1:INOUT); - - case IN_OUT_IN : - auxp1 = BOP_intersectPlane(m_plane, p2, p1); - auxp2 = BOP_intersectPlane(m_plane, p2, p3); - - // f1: auxp1 p2 , p2 auxp2 - auxtag1 = classifyFaceOUT(auxp1, p2, auxp2, plane); - - // f2: p1 auxp1 , auxp1 auxp2; f3: p1 auxp2 , auxp2 p3 || - // f2: p3 auxp1, auxp1 auxp2 f3:p1 auxp1, auxp1 p3 - if (BOP_isInsideCircle(p1, p3, auxp1, auxp2)) { - auxtag2 = classifyFaceIN(p1, auxp1, auxp2, plane); - auxtag3 = classifyFaceIN(p1, auxp2, p3, plane); - } - else { - auxtag2 = classifyFaceIN(p3, auxp1, auxp2, plane); - auxtag3 = classifyFaceIN(p1, auxp1, p3, plane); - } - return (BOP_compTAG(auxtag1,auxtag2)&&BOP_compTAG(auxtag2,auxtag3)?auxtag1:INOUT); - - case OUT_OUT_IN : - auxp1 = BOP_intersectPlane(m_plane, p3, p1); - auxp2 = BOP_intersectPlane(m_plane, p3, p2); - - // f1: auxp1 auxp2 , auxp2 p3 - auxtag1 = classifyFaceIN(auxp1, auxp2, p3, plane); - - // f2: p1 p2 , p2 auxp2; f3:p1 auxp2 , auxp2 auxp1 || - // f2: p1 p2, p2 auxp1; f3:p2 auxp2, auxp2 auxp1 - if (BOP_isInsideCircle(p1, p2, auxp1, auxp2)) { - auxtag2 = classifyFaceOUT(p1, p2, auxp2, plane); - auxtag3 = classifyFaceOUT(p1, auxp2, auxp1, plane); - } - else { - auxtag2 = classifyFaceOUT(p1, p2, auxp1, plane); - auxtag3 = classifyFaceOUT(p2, auxp2, auxp1, plane); - } - return (BOP_compTAG(auxtag1,auxtag2)&&BOP_compTAG(auxtag2,auxtag3)?auxtag1:INOUT); - - case IN_IN_OUT : - auxp1 = BOP_intersectPlane(m_plane, p3, p1); - auxp2 = BOP_intersectPlane(m_plane, p3, p2); - - // f1: auxp1 auxp2 , auxp2 p3 - auxtag1 = classifyFaceOUT(auxp1, auxp2, p3, plane); - - // f2: p1 p2 , p2 auxp2; f3:p1 auxp2 , auxp2 auxp1 || - // f2: p1 p2, p2 auxp1; f3:p2 auxp2, auxp2 auxp1 - if (BOP_isInsideCircle(p1, p2, auxp1, auxp2)) { - auxtag2 = classifyFaceIN(p1, p2, auxp2, plane); - auxtag3 = classifyFaceIN(p1, auxp2, auxp1, plane); - } - else { - auxtag2 = classifyFaceIN(p1, p2, auxp1, plane); - auxtag3 = classifyFaceIN(p2, auxp2, auxp1, plane); - } - return (BOP_compTAG(auxtag1,auxtag2)&&BOP_compTAG(auxtag2,auxtag3)?auxtag1:INOUT); - - default: - return UNCLASSIFIED; - } -} - -/** - * Classifies a face through IN subtree. - * @param p1 firts face vertex. - * @param p2 second face vertex. - * @param p3 third face vertex. - * @param plane face plane. - */ -BOP_TAG BOP_BSPNode::classifyFaceIN(const MT_Point3& p1, - const MT_Point3& p2, - const MT_Point3& p3, - const MT_Plane3& plane) const -{ - if (m_inChild != NULL) - return m_inChild->classifyFace(p1, p2, p3, plane); - else - return IN; -} - -/** - * Classifies a face through OUT subtree. - * @param p1 firts face vertex. - * @param p2 second face vertex. - * @param p3 third face vertex. - * @param plane face plane. - */ -BOP_TAG BOP_BSPNode::classifyFaceOUT(const MT_Point3& p1, - const MT_Point3& p2, - const MT_Point3& p3, - const MT_Plane3& plane) const -{ - if (m_outChild != NULL) - return m_outChild->classifyFace(p1, p2, p3, plane); - else - return OUT; -} - -/** - * Simplified classification (optimized but requires that the face is not - * INOUT; only works correctly with faces completely IN or OUT). - * @param p1 firts face vertex. - * @param p2 second face vertex. - * @param p3 third face vertex. - * @param plane face plane. - * @return TAG result: IN or OUT. - */ -BOP_TAG BOP_BSPNode::simplifiedClassifyFace(const MT_Point3& p1, - const MT_Point3& p2, - const MT_Point3& p3, - const MT_Plane3& plane) const -{ - MT_Point3 ret[3]; - - BOP_TAG tag = BOP_createTAG(testPoint(p1),testPoint(p2),testPoint(p3)); - - if ((tag & IN_IN_IN) != 0) { - if ((tag & OUT_OUT_OUT) != 0) { - if (splitTriangle(ret,m_plane,p1,p2,p3,tag)<0) - return simplifiedClassifyFaceIN(ret[0],ret[1],ret[2],plane); - else - return simplifiedClassifyFaceOUT(ret[0],ret[1],ret[2],plane); - } - else { - return simplifiedClassifyFaceIN(p1,p2,p3,plane); - } - } - else { - if ((tag & OUT_OUT_OUT) != 0) { - return simplifiedClassifyFaceOUT(p1,p2,p3,plane); - } - else { - if (hasSameOrientation(plane)) { - return simplifiedClassifyFaceIN(p1,p2,p3,plane); - } - else { - return simplifiedClassifyFaceOUT(p1,p2,p3,plane); - } - } - } - - return IN; -} - -/** - * Simplified classify through IN subtree. - * @param p1 firts face vertex. - * @param p2 second face vertex. - * @param p3 third face vertex. - * @param plane face plane. - */ -BOP_TAG BOP_BSPNode::simplifiedClassifyFaceIN(const MT_Point3& p1, - const MT_Point3& p2, - const MT_Point3& p3, - const MT_Plane3& plane) const -{ - if (m_inChild != NULL) - return m_inChild->simplifiedClassifyFace(p1, p2, p3, plane); - else - return IN; -} - -/** - * Simplified classify through OUT subtree. - * @param p1 firts face vertex. - * @param p2 second face vertex. - * @param p3 third face vertex. - * @param plane face plane. - */ -BOP_TAG BOP_BSPNode::simplifiedClassifyFaceOUT(const MT_Point3& p1, - const MT_Point3& p2, - const MT_Point3& p3, - const MT_Plane3& plane) const -{ - if (m_outChild != NULL) - return m_outChild->simplifiedClassifyFace(p1, p2, p3, plane); - else - return OUT; -} - -/** - * Determine if the input plane have the same orientation of the node plane. - * @param plane plane to test. - * @return TRUE if have the same orientation, FALSE otherwise. - */ -bool BOP_BSPNode::hasSameOrientation(const MT_Plane3& plane) const -{ - return (BOP_orientation(m_plane,plane)>0); -} - -/** - * Comparation between both childrens. - * @return 0 equal deep, 1 inChild more deep than outChild and -1 otherwise. - */ -int BOP_BSPNode::compChildren() const -{ - unsigned int deep1 = (m_inChild == NULL?0:m_inChild->getDeep()); - unsigned int deep2 = (m_outChild == NULL?0:m_outChild->getDeep()); - - if (deep1 == deep2) - return 0; - else if (deep1 < deep2) - return -1; - else - return 1; -} - -/** - * Extract a subtriangle from input triangle, is used for simplified classification. - * The subtriangle is obtained spliting the input triangle by input plane. - * @param res output subtriangle result. - * @param plane spliter plane. - * @param p1 first triangle point. - * @param p2 second triangle point. - * @param p3 third triangle point. - * @param tag triangle orientation respect the plane. - */ -int BOP_BSPNode::splitTriangle(MT_Point3* res, - const MT_Plane3& plane, - const MT_Point3& p1, - const MT_Point3& p2, - const MT_Point3& p3, - const BOP_TAG tag) const -{ - switch (tag) { - case IN_OUT_ON : - if (compChildren()<0) { - // f1: p1 new p3 || new = splitedge(p1,p2) - res[0] = p1; - res[1] = BOP_intersectPlane( plane, p1, p2 ); - res[2] = p3; - return -1; - }else{ - // f1: p2 new p3 || new = splitedge(p1,p2) - res[0] = p2; - res[1] = p3; - res[2] = BOP_intersectPlane( plane, p1, p2 ); - return 1; - } - case OUT_IN_ON : - if (compChildren()<0) { - // f1: p2 new p3 || new = splitedge(p1,p2) - res[0] = p2; - res[1] = p3; - res[2] = BOP_intersectPlane( plane, p1, p2 ); - return -1; - }else{ - // f1: p1 new p3 || new = splitedge(p1,p2) - res[0] = p1; - res[1] = BOP_intersectPlane( plane, p1, p2 ); - res[2] = p3; - return 1; - } - case IN_ON_OUT : - if (compChildren()<0) { - // f1: p1 p2 new || new = splitedge(p1,p3) - res[0] = p1; - res[1] = p2; - res[2] = BOP_intersectPlane( plane, p1, p3 ); - return -1; - }else{ - // f1: p2 p3 new || new = splitedge(p1,p3) - res[0] = p2; - res[1] = p3; - res[2] = BOP_intersectPlane( plane, p1, p3 ); - return 1; - } - case OUT_ON_IN : - if (compChildren()<0) { - // f1: p2 p3 new || new = splitedge(p1,p3) - res[0] = p2; - res[1] = p3; - res[2] = BOP_intersectPlane( plane, p1, p3 ); - return -1; - }else{ - // f1: p1 p2 new || new = splitedge(p1,p3) - res[0] = p1; - res[1] = p2; - res[2] = BOP_intersectPlane( plane, p1, p3 ); - return 1; - } - case ON_IN_OUT : - if (compChildren()<0) { - // f1: p1 p2 new || new = splitedge(p2,p3) - res[0] = p1; - res[1] = p2; - res[2] = BOP_intersectPlane( plane, p2, p3 ); - return -1; - }else{ - // f1: p1 p3 new || new = splitedge(p2,p3) - res[0] = p1; - res[1] = BOP_intersectPlane( plane, p2, p3 ); - res[2] = p3; - return 1; - } - case ON_OUT_IN : - if (compChildren()<0) { - // f1: p1 p2 new || new = splitedge(p2,p3) - res[0] = p1; - res[1] = BOP_intersectPlane( plane, p2, p3 ); - res[2] = p3; - return -1; - }else{ - // f1: p1 p2 new || new = splitedge(p2,p3) - res[0] = p1; - res[1] = p2; - res[2] = BOP_intersectPlane( plane, p2, p3 ); - return 1; - } - case IN_OUT_OUT : - if (compChildren()<=0) { - // f1: p1 new1 new2 || new1 = splitedge(p1,p2) new2 = splitedge(p1,p3) - res[0] = p1; - res[1] = BOP_intersectPlane( plane, p1, p2 ); - res[2] = BOP_intersectPlane( plane, p1, p3 ); - return -1; - }else{ - // f1: p1 new1 new2 || new1 = splitedge(p1,p2) new2 = splitedge(p1,p3) - res[0] = BOP_intersectPlane( plane, p1, p2 ); - res[1] = p2; - res[2] = p3; - return 1; - } - case OUT_IN_IN : - if (compChildren()<0) { - // f1: p1 new1 new2 || new1 = splitedge(p1,p2) new2 = splitedge(p1,p3) - res[0] = BOP_intersectPlane( plane, p1, p2 ); - res[1] = p2; - res[2] = p3; - return -1; - }else { - // f1: p1 new1 new2 || new1 = splitedge(p1,p2) new2 = splitedge(p1,p3) - res[0] = p1; - res[1] = BOP_intersectPlane( plane, p1, p2 ); - res[2] = BOP_intersectPlane( plane, p1, p3 ); - return 1; - } - case OUT_IN_OUT : - if (compChildren()<=0) { - // f1: new1 p2 new2 || new1 = splitedge(p2,p1) new2 = splitedge(p2,p3) - res[0] = BOP_intersectPlane( plane, p2, p1 ); - res[1] = p2; - res[2] = BOP_intersectPlane( plane, p2, p3 ); - return -1; - }else { - // f1: new1 p2 new2 || new1 = splitedge(p2,p1) new2 = splitedge(p2,p3) - res[0] = p1; - res[1] = BOP_intersectPlane( plane, p2, p1 ); - res[2] = BOP_intersectPlane( plane, p2, p3 ); - return 1; - } - case IN_OUT_IN : - if (compChildren()<0) { - // f1: new1 p2 new2 || new1 = splitedge(p2,p1) new2 = splitedge(p2,p3) - res[0] = p1; - res[1] = BOP_intersectPlane( plane, p2, p1 ); - res[2] = BOP_intersectPlane( plane, p2, p3 ); - return -1; - }else{ - // f1: new1 p2 new2 || new1 = splitedge(p2,p1) new2 = splitedge(p2,p3) - res[0] = BOP_intersectPlane( plane, p2, p1 ); - res[1] = p2; - res[2] = BOP_intersectPlane( plane, p2, p3 ); - return 1; - } - case OUT_OUT_IN : - if (compChildren()<=0) { - // f1: new1 new2 p2 || new1 = splitedge(p3,p1) new2 = splitedge(p3,p2) - res[0] = BOP_intersectPlane( plane, p3, p1 ); - res[1] = BOP_intersectPlane( plane, p3, p2 ); - res[2] = p3; - return -1; - }else{ - // f1: new1 new2 p2 || new1 = splitedge(p3,p1) new2 = splitedge(p3,p2) - res[0] = BOP_intersectPlane( plane, p3, p1 ); - res[1] = p1; - res[2] = p2; - return 1; - } - case IN_IN_OUT : - if (compChildren()<0) { - // f1: new1 new2 p2 || new1 = splitedge(p3,p1) new2 = splitedge(p3,p2) - res[0] = BOP_intersectPlane( plane, p3, p1 ); - res[1] = p1; - res[2] = p2; - return -1; - }else{ - // f1: new1 new2 p2 || new1 = splitedge(p3,p1) new2 = splitedge(p3,p2) - res[0] = BOP_intersectPlane( plane, p3, p1 ); - res[1] = BOP_intersectPlane( plane, p3, p2 ); - res[2] = p3; - return 1; - } - default: - return 0; - } -} - -/** - * Debug info. - */ -void BOP_BSPNode::print(unsigned int deep) -{ - std::cout << "(" << deep << "," << m_plane << ")," << std::endl; - if (m_inChild != NULL) - m_inChild->print(deep + 1); - else - std::cout << "(" << deep+1 << ",None)," << std::endl; - if (m_outChild != NULL) - m_outChild->print(deep + 1); - else - std::cout << "(" << deep+1 << ",None)," << std::endl; -} diff --git a/intern/boolop/intern/BOP_BSPNode.h b/intern/boolop/intern/BOP_BSPNode.h deleted file mode 100644 index e8646cd904c..00000000000 --- a/intern/boolop/intern/BOP_BSPNode.h +++ /dev/null @@ -1,107 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file boolop/intern/BOP_BSPNode.h - * \ingroup boolopintern - */ - - -#ifndef __BOP_BSPNODE_H__ -#define __BOP_BSPNODE_H__ - -#include "MT_Plane3.h" -#include "BOP_Tag.h" -#include "BOP_Face.h" - -typedef std::vector<MT_Point3> BOP_BSPPoints; -typedef std::vector<MT_Point3>::const_iterator BOP_IT_BSPPoints; - -class BOP_BSPNode -{ -protected: - BOP_BSPNode* m_inChild; - BOP_BSPNode* m_outChild; - MT_Plane3 m_plane; - unsigned int m_deep; - -public: - // Construction methods - BOP_BSPNode(const MT_Plane3& plane); - ~BOP_BSPNode(); - unsigned int addFace(const BOP_BSPPoints& pts, - const MT_Plane3& plane); - BOP_TAG classifyFace(const MT_Point3& p1, - const MT_Point3& p2, - const MT_Point3& p3, - const MT_Plane3& plane) const; - BOP_TAG simplifiedClassifyFace(const MT_Point3& p1, - const MT_Point3& p2, - const MT_Point3& p3, - const MT_Plane3& plane) const; - -protected: - BOP_TAG testPoint(const MT_Point3& p) const; - BOP_TAG classifyFaceIN(const MT_Point3& p1, - const MT_Point3& p2, - const MT_Point3& p3, - const MT_Plane3& plane) const; - BOP_TAG classifyFaceOUT(const MT_Point3& p1, - const MT_Point3& p2, - const MT_Point3& p3, - const MT_Plane3& plane) const; - BOP_TAG simplifiedClassifyFaceIN(const MT_Point3& p1, - const MT_Point3& p2, - const MT_Point3& p3, - const MT_Plane3& plane) const; - BOP_TAG simplifiedClassifyFaceOUT(const MT_Point3& p1, - const MT_Point3& p2, - const MT_Point3& p3, - const MT_Plane3& plane) const; - bool hasSameOrientation(const MT_Plane3& plane) const; - int compChildren() const; - int splitTriangle(MT_Point3* res, - const MT_Plane3& plane, - const MT_Point3& p1, - const MT_Point3& p2, - const MT_Point3& p3, - const BOP_TAG tag) const; - -public: - // Inline acces methods - inline void setInChild(BOP_BSPNode* inChild) { m_inChild=inChild; }; - inline void setOutChild(BOP_BSPNode* outChild) { m_outChild=outChild; }; - inline BOP_BSPNode* getInChild() { return m_inChild; }; - inline BOP_BSPNode* getOutChild() { return m_outChild; }; - inline bool isLeaf() const { return !m_inChild && !m_outChild; }; - inline void setPlane(const MT_Plane3& plane) {m_plane=plane;}; - inline MT_Plane3& getPlane() { return m_plane; }; - - inline unsigned int getDeep() const {return m_deep;}; - void print(unsigned int deep); -}; - -#endif diff --git a/intern/boolop/intern/BOP_BSPTree.cpp b/intern/boolop/intern/BOP_BSPTree.cpp deleted file mode 100644 index 7a8ed417be4..00000000000 --- a/intern/boolop/intern/BOP_BSPTree.cpp +++ /dev/null @@ -1,190 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file boolop/intern/BOP_BSPTree.cpp - * \ingroup boolopintern - */ - - -#include "BOP_BSPTree.h" -#include <vector> -#include <iostream> - -/** - * Constructs a new BSP tree. - */ -BOP_BSPTree::BOP_BSPTree() -{ - m_root = NULL; - m_bspBB = NULL; -} - -/** - * Destroys a BSP tree. - */ -BOP_BSPTree::~BOP_BSPTree() -{ - if (m_root!=NULL) delete m_root; - if (m_bspBB!=NULL) delete m_bspBB; -} - -/** - * Adds all mesh faces to BSP tree. - * @param mesh mesh to add. - * @param facesList face list to add. - */ -void BOP_BSPTree::addMesh(BOP_Mesh* mesh, BOP_Faces& facesList) -{ - for (BOP_IT_Faces it = facesList.begin(); it != facesList.end(); ++it) { - addFace( mesh, *it ); - } - -} - -/** - * Adds a new face into bsp tree. - * @param mesh Input data for BSP tree. - * @param face index to mesh face. - */ - -void BOP_BSPTree::addFace(BOP_Mesh* mesh, BOP_Face* face) -{ - addFace(mesh->getVertex(face->getVertex(0))->getPoint(), - mesh->getVertex(face->getVertex(1))->getPoint(), - mesh->getVertex(face->getVertex(2))->getPoint(), - face->getPlane()); -} - -/** - * Adds new facee to the bsp-tree. - * @param p1 first face point. - * @param p2 second face point. - * @param p3 third face point. - * @param plane face plane. - */ -void BOP_BSPTree::addFace(const MT_Point3& p1, - const MT_Point3& p2, - const MT_Point3& p3, - const MT_Plane3& plane) -{ - if (m_root == NULL) - m_root = new BOP_BSPNode(plane); - else { - BOP_BSPPoints pts; - - pts.push_back(p1); - pts.push_back(p2); - pts.push_back(p3); - - m_root->addFace(pts,plane); - } - - // update bounding box - m_bbox.add(p1); - m_bbox.add(p2); - m_bbox.add(p3); -} - -/** - * Tests face vs bsp-tree (returns where is the face respect bsp planes). - * @param p1 first face triangle point. - * @param p2 secons face triangle point. - * @param p3 third face triangle point. - * @param plane face plane. - * @return BSP_IN, BSP_OUT or BSP_IN_OUT - */ -BOP_TAG BOP_BSPTree::classifyFace(const MT_Point3& p1, - const MT_Point3& p2, - const MT_Point3& p3, - const MT_Plane3& plane) const -{ - if ( m_root != NULL ) - return m_root->classifyFace(p1, p2, p3, plane); - else - return OUT; -} - -/** - * Filters a face using the BSP bounding infomation. - * @param p1 first face triangle point. - * @param p2 secons face triangle point. - * @param p3 third face triangle point. - * @param face face to test. - * @return UNCLASSIFIED, BSP_IN, BSP_OUT or BSP_IN_OUT - */ -BOP_TAG BOP_BSPTree::filterFace(const MT_Point3& p1, - const MT_Point3& p2, - const MT_Point3& p3, - BOP_Face* face) -{ - if ( m_bspBB != NULL ) { - return m_bspBB->classifyFace(p1,p2,p3,face->getPlane()); - } - else - return UNCLASSIFIED; -} - -/** - * Tests face vs bsp-tree (returns where is the face respect bsp planes). - * @param p1 first face triangle point. - * @param p2 secons face triangle point. - * @param p3 third face triangle point. - * @param plane face plane. - * @return BSP_IN, BSP_OUT or BSP_IN_OUT - */ -BOP_TAG BOP_BSPTree::simplifiedClassifyFace(const MT_Point3& p1, - const MT_Point3& p2, - const MT_Point3& p3, - const MT_Plane3& plane) const -{ - if ( m_root != NULL ) - return m_root->simplifiedClassifyFace(p1, p2, p3, plane); - else - return OUT; -} - -/** - * Returns the deep of this BSP tree. - * @return tree deep - */ -unsigned int BOP_BSPTree::getDeep() const -{ - if ( m_root != NULL ) - return m_root->getDeep(); - else - return 0; -} - -/** - * Prints debug information. - */ -void BOP_BSPTree::print() -{ - if ( m_root != NULL ) - m_root->print( 0 ); -} - diff --git a/intern/boolop/intern/BOP_BSPTree.h b/intern/boolop/intern/BOP_BSPTree.h deleted file mode 100644 index b3abd55bf2a..00000000000 --- a/intern/boolop/intern/BOP_BSPTree.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file boolop/intern/BOP_BSPTree.h - * \ingroup boolopintern - */ - - -#ifndef __BOP_BSPTREE_H__ -#define __BOP_BSPTREE_H__ - -#include "BOP_BSPNode.h" -#include "BOP_Mesh.h" -#include "BOP_Tag.h" -#include "BOP_BBox.h" - -class BOP_BSPTree -{ -protected: - BOP_BSPNode* m_root; - BOP_BSPNode* m_bspBB; - BOP_BBox m_bbox; -public: - // Construction methods - BOP_BSPTree(); - virtual ~BOP_BSPTree(); - void addMesh(BOP_Mesh* mesh, BOP_Faces& facesList); - void addFace(BOP_Mesh* mesh, BOP_Face* face); - virtual void addFace(const MT_Point3& p1, - const MT_Point3& p2, - const MT_Point3& p3, - const MT_Plane3& plane); - BOP_TAG classifyFace(const MT_Point3& p1, - const MT_Point3& p2, - const MT_Point3& p3, - const MT_Plane3& plane) const; - BOP_TAG filterFace(const MT_Point3& p1, - const MT_Point3& p2, - const MT_Point3& p3, - BOP_Face* face); - BOP_TAG simplifiedClassifyFace(const MT_Point3& p1, - const MT_Point3& p2, - const MT_Point3& p3, - const MT_Plane3& plane) const; - unsigned int getDeep() const; - void print(); - inline void setRoot(BOP_BSPNode* root) {m_root=root;}; - inline BOP_BSPNode* getRoot() const {return m_root;}; -}; - -#endif - diff --git a/intern/boolop/intern/BOP_Chrono.h b/intern/boolop/intern/BOP_Chrono.h deleted file mode 100644 index 8f09eeae82e..00000000000 --- a/intern/boolop/intern/BOP_Chrono.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file boolop/intern/BOP_Chrono.h - * \ingroup boolopintern - */ - - -#ifndef __BOP_CHRONO_H__ -#define __BOP_CHRONO_H__ - -#include <time.h> - -class BOP_Chrono -{ -private: - clock_t m_begin; -public: - BOP_Chrono(){}; - void start() {m_begin = clock();}; - float stamp() { - clock_t c = clock(); - clock_t stmp = c - m_begin; - m_begin = c; - float t = ((float) stmp / (float) CLOCKS_PER_SEC)*1000.0f; - return t; - }; -}; - -#endif diff --git a/intern/boolop/intern/BOP_Edge.cpp b/intern/boolop/intern/BOP_Edge.cpp deleted file mode 100644 index fc03dd897d3..00000000000 --- a/intern/boolop/intern/BOP_Edge.cpp +++ /dev/null @@ -1,125 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file boolop/intern/BOP_Edge.cpp - * \ingroup boolopintern - */ - - -#include "BOP_Edge.h" - -/** - * Constructs a new edge. - * @param v1 vertex index - * @param v2 vertex index - */ -BOP_Edge::BOP_Edge(BOP_Index v1, BOP_Index v2) -{ - m_vertexs[0] = v1; - m_vertexs[1] = v2; -} - -/** - * Adds a new face index to this edge. - * @param i face index - */ -void BOP_Edge::addFace(BOP_Index i) -{ - if (!containsFace(i)) - m_faces.push_back(i); -} - -/** - * Returns if this edge contains the specified face index. - * @param i face index - * @return true if this edge contains the specified face index, false otherwise - */ -bool BOP_Edge::containsFace(BOP_Index i) -{ - int pos=0; - for(BOP_IT_Indexs it = m_faces.begin();it!=m_faces.end();pos++,it++) { - if ((*it) == i) - return true; - } - - return false; -} - -/** - * Replaces an edge vertex index. - * @param oldIndex old vertex index - * @param newIndex new vertex index - */ -void BOP_Edge::replaceVertexIndex(BOP_Index oldIndex, BOP_Index newIndex) -{ - if (m_vertexs[0] == oldIndex) m_vertexs[0] = newIndex; - else if (m_vertexs[1] == oldIndex) m_vertexs[1] = newIndex; -} - -#ifdef BOP_NEW_MERGE - -/** - * Returns if this edge contains the specified face index. - * @param i face index - * @return true if this edge contains the specified face index, false otherwise - */ -bool BOP_Edge::removeFace(BOP_Index i) -{ - int pos=0; - for(BOP_IT_Indexs it = m_faces.begin();it!=m_faces.end();pos++,it++) { - if ((*it) == i) { - m_faces.erase(it); - return true; - } - } - - return false; -} - -#endif - -#ifdef BOP_DEBUG - -#include <iostream> - -/** - * Implements operator <<. - */ -ostream &operator<<(ostream &stream, BOP_Edge *e) -{ - stream << "Edge[" << e->getVertex1() << "," << e->getVertex2(); -#ifdef BOP_NEW_MERGE - if(e->m_used) - stream << "] (used)"; - else - stream << "] (unused)"; -#endif - return stream; -} -#endif - - diff --git a/intern/boolop/intern/BOP_Edge.h b/intern/boolop/intern/BOP_Edge.h deleted file mode 100644 index fd2f53b1aa4..00000000000 --- a/intern/boolop/intern/BOP_Edge.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file boolop/intern/BOP_Edge.h - * \ingroup boolopintern - */ - - -#ifndef __BOP_EDGE_H__ -#define __BOP_EDGE_H__ - -#include "BOP_Indexs.h" -#include "BOP_Misc.h" - -class BOP_Edge -{ -private: - BOP_Index m_vertexs[2]; - BOP_Indexs m_faces; -#ifdef BOP_NEW_MERGE - bool m_used; -#endif - - bool containsFace(BOP_Index i); - -public: - BOP_Edge(BOP_Index v1, BOP_Index v2); - inline BOP_Index getVertex1() { return m_vertexs[0];}; - inline BOP_Index getVertex2() { return m_vertexs[1];}; - void replaceVertexIndex(BOP_Index oldIndex, BOP_Index newIndex); - inline BOP_Index getFace(unsigned int i){return m_faces[i];}; - inline unsigned int getNumFaces(){return m_faces.size();}; - inline BOP_Indexs &getFaces(){return m_faces;}; - void addFace(BOP_Index face); -#ifdef BOP_NEW_MERGE - bool removeFace(BOP_Index i); - bool getUsed() { return m_used;}; - void setUsed(bool setting) { m_used=setting;}; -#endif -#ifdef BOP_DEBUG - friend ostream &operator<<(ostream &stream, BOP_Edge *e); -#endif - -}; - -#endif diff --git a/intern/boolop/intern/BOP_Face.cpp b/intern/boolop/intern/BOP_Face.cpp deleted file mode 100644 index 651964f4dbd..00000000000 --- a/intern/boolop/intern/BOP_Face.cpp +++ /dev/null @@ -1,430 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file boolop/intern/BOP_Face.cpp - * \ingroup boolopintern - */ - - -#include "BOP_Face.h" - -/******************************************************************************/ -/*** BOP_Face ***/ -/******************************************************************************/ - -/** - * Constructs a new face. - * @param plane face plane - * @param originalFace index of the original face - */ -BOP_Face::BOP_Face(MT_Plane3 plane, BOP_Index originalFace) -{ - m_plane = plane; - m_tag = UNCLASSIFIED; - m_originalFace = originalFace; - m_split = 0; - m_bbox = NULL; -} - -/** - * Inverts this face. - */ -void BOP_Face::invert() -{ - getPlane().Invert(); - BOP_Index aux = m_indexs[0]; - m_indexs[0] = m_indexs[2]; - m_indexs[2] = aux; -} - -/******************************************************************************/ -/*** BOP_Face ***/ -/******************************************************************************/ - -/** - * Constructs a new triangle face. - * @param v1 vertex index - * @param v2 vertex index - * @param v3 vertex index - * @param plane face plane - * @param originalFace index of the original face - */ -BOP_Face3::BOP_Face3(BOP_Index v1, BOP_Index v2, BOP_Index v3, MT_Plane3 plane, BOP_Index originalFace): BOP_Face(plane,originalFace) -{ - m_indexs[0] = v1; - m_indexs[1] = v2; - m_indexs[2] = v3; - m_size = 3; -} - -/** - * Returns the relative edge index (1,2,3) for the specified vertex indexs. - * @param v1 vertex index - * @param v2 vertex index - * @param e relative edge index (1,2,3) - * @return true if (v1,v2) is an edge of this face, false otherwise - */ -bool BOP_Face3::getEdgeIndex(BOP_Index v1, BOP_Index v2, unsigned int &e) -{ - if (m_indexs[0] == v1) { - if (m_indexs[1] == v2) { - e = 1; - } - else if (m_indexs[2] == v2) { - e = 3; - } - else - return false; - } - else if (m_indexs[1] == v1) { - if (m_indexs[0] == v2) { - e = 1; - } - else if (m_indexs[2] == v2) { - e = 2; - } - else - return false; - } - else if (m_indexs[2] == v1) { - if (m_indexs[0] == v2) { - e = 3; - } - else if (m_indexs[1] == v2) { - e = 2; - } - else - return false; - }else { - return false; - } - - return true; -} - -/** - * Returns if this face contains the specified vertex index. - * @param v vertex index - * @return true if this face contains the specified vertex index, false otherwise - */ -bool BOP_Face3::containsVertex(BOP_Index v) -{ - return (m_indexs[0] == v || m_indexs[1] == v || m_indexs[2] == v); -} - -/** - * Returns the neighbours of the specified vertex index. - * @param v vertex index - * @param prev previous vertex index - * @param next next vertex index - * @return true if this face contains the vertex index v, false otherwise - */ -bool BOP_Face3::getNeighbours(BOP_Index v, BOP_Index &prev, BOP_Index &next) -{ - if (m_indexs[0] == v) { - prev = m_indexs[2]; - next = m_indexs[1]; - } - else if (m_indexs[1] == v) { - prev = m_indexs[0]; - next = m_indexs[2]; - } - else if (m_indexs[2] == v) { - prev = m_indexs[1]; - next = m_indexs[0]; - } - else return false; - - return true; -} - -/** - * Returns the previous neighbour of the specified vertex index. - * @param v vertex index - * @param w previous vertex index - * @return true if this face contains the specified vertex index, false otherwise - */ -bool BOP_Face3::getPreviousVertex(BOP_Index v, BOP_Index &w) -{ - if (m_indexs[0] == v) w = m_indexs[2]; - else if (m_indexs[1] == v) w = m_indexs[0]; - else if (m_indexs[2] == v) w = m_indexs[1]; - else return false; - - return true; -} - -/** - * Returns the next neighbour of the specified vertex index. - * @param v vertex index - * @param w vertex index - * @return true if this face contains the specified vertex index, false otherwise - */ -bool BOP_Face3::getNextVertex(BOP_Index v, BOP_Index &w) -{ - if (m_indexs[0] == v) w = m_indexs[1]; - else if (m_indexs[1] == v) w = m_indexs[2]; - else if (m_indexs[2] == v) w = m_indexs[0]; - else return false; - - return true; -} - -/** - * Replaces a face vertex index. - * @param oldIndex old vertex index - * @param newIndex new vertex index - */ -void BOP_Face3::replaceVertexIndex(BOP_Index oldIndex, BOP_Index newIndex) -{ - /* if the old index really exists, and new index also exists already, - * don't create an edge with both vertices == newIndex */ - - if( (m_indexs[0] == oldIndex || m_indexs[1] == oldIndex || m_indexs[2] == oldIndex) && - (m_indexs[0] == newIndex || m_indexs[1] == newIndex || m_indexs[2] == newIndex) ) { - setTAG(BROKEN); - } - - if (m_indexs[0] == oldIndex) m_indexs[0] = newIndex; - else if (m_indexs[1] == oldIndex) m_indexs[1] = newIndex; - else if (m_indexs[2] == oldIndex) m_indexs[2] = newIndex; -} - -/******************************************************************************/ -/*** BOP_Face4 ***/ -/******************************************************************************/ - -/** - * Constructs a new quad face. - * @param v1 vertex index - * @param v2 vertex index - * @param v3 vertex index - * @param v4 vertex index - * @param plane face plane - * @param originalFace index of the original face - */ -BOP_Face4::BOP_Face4(BOP_Index v1, BOP_Index v2, BOP_Index v3, BOP_Index v4, MT_Plane3 plane, - BOP_Index originalFace): - BOP_Face(plane,originalFace) -{ - m_indexs[0] = v1; - m_indexs[1] = v2; - m_indexs[2] = v3; - m_indexs[3] = v4; - - m_size = 4; -} - -/** - * Returns if this face contains the specified vertex index. - * @param v vertex index - * @return true if this face contains the specified vertex index, false otherwise - */ -bool BOP_Face4::containsVertex(BOP_Index v) -{ - return (m_indexs[0] == v || m_indexs[1] == v || m_indexs[2] == v || m_indexs[3]==v); -} - -/** - * Returns the neighbours of the specified vertex index. - * @param v vertex index - * @param prev previous vertex index - * @param next next vertex index - * @param opp opposite vertex index - * @return true if this face contains the vertex index v, false otherwise - */ -bool BOP_Face4::getNeighbours(BOP_Index v, BOP_Index &prev, BOP_Index &next, BOP_Index &opp) -{ - if (m_indexs[0] == v) { - prev = m_indexs[3]; - next = m_indexs[1]; - opp = m_indexs[2]; - } - else if (m_indexs[1] == v) { - prev = m_indexs[0]; - next = m_indexs[2]; - opp = m_indexs[3]; - } - else if (m_indexs[2] == v) { - prev = m_indexs[1]; - next = m_indexs[3]; - opp = m_indexs[0]; - } - else if (m_indexs[3] == v) { - prev = m_indexs[2]; - next = m_indexs[0]; - opp = m_indexs[1]; - } - else return false; - - return true; -} - -/** - * Returns the previous neighbour of the specified vertex index. - * @param v vertex index - * @param w previous vertex index - * @return true if this face contains the specified vertex index, false otherwise - */ -bool BOP_Face4::getPreviousVertex(BOP_Index v, BOP_Index &w) -{ - if (m_indexs[0] == v) w = m_indexs[3]; - else if (m_indexs[1] == v) w = m_indexs[0]; - else if (m_indexs[2] == v) w = m_indexs[1]; - else if (m_indexs[3] == v) w = m_indexs[2]; - else return false; - - return true; -} - -/** - * Returns the next neighbour of the specified vertex index. - * @param v vertex index - * @param w next vertex index - * @return true if this face contains the specified vertex index, false otherwise - */ -bool BOP_Face4::getNextVertex(BOP_Index v, BOP_Index &w) -{ - if (m_indexs[0] == v) w = m_indexs[1]; - else if (m_indexs[1] == v) w = m_indexs[2]; - else if (m_indexs[2] == v) w = m_indexs[3]; - else if (m_indexs[3] == v) w = m_indexs[0]; - else return false; - - return true; -} - -/** - * Returns the opposite neighbour of the specified vertex index. - * @param v vertex index - * @param w opposite vertex index - * @return true if this face contains the specified vertex index, false otherwise - */ -bool BOP_Face4::getOppositeVertex(BOP_Index v, BOP_Index &w) -{ - if (m_indexs[0] == v) - w = m_indexs[2]; - else if (m_indexs[1] == v) - w = m_indexs[3]; - else if (m_indexs[2] == v) - w = m_indexs[0]; - else if (m_indexs[3] == v) - w = m_indexs[1]; - else - return false; - - return true; -} - -/** - * Replaces a face vertex index. - * @param oldIndex old vertex index - * @param newIndex new vertex index - */ -void BOP_Face4::replaceVertexIndex(BOP_Index oldIndex, BOP_Index newIndex) -{ - if (m_indexs[0] == oldIndex) m_indexs[0] = newIndex; - else if (m_indexs[1] == oldIndex) m_indexs[1] = newIndex; - else if (m_indexs[2] == oldIndex) m_indexs[2] = newIndex; - else if (m_indexs[3] == oldIndex) m_indexs[3] = newIndex; -} - -/** - * Returns the relative edge index (1,2,3,4) for the specified vertex indexs. - * @param v1 vertex index - * @param v2 vertex index - * @param e relative edge index (1,2,3,4) - * @return true if (v1,v2) is an edge of this face, false otherwise - */ -bool BOP_Face4::getEdgeIndex(BOP_Index v1, BOP_Index v2, unsigned int &e) -{ - if (m_indexs[0] == v1) { - if (m_indexs[1] == v2) { - e = 1; - } - else if (m_indexs[3] == v2) { - e = 4; - } - else - return false; - } - else if (m_indexs[1] == v1) { - if (m_indexs[0] == v2) { - e = 1; - } - else if (m_indexs[2] == v2) { - e = 2; - } - else - return false; - } - else if (m_indexs[2] == v1) { - if (m_indexs[1] == v2) { - e = 2; - } - else if (m_indexs[3] == v2) { - e = 3; - } - else - return false; - } - else if (m_indexs[3] == v1) { - if (m_indexs[2] == v2) { - e = 3; - } - else if (m_indexs[0] == v2) { - e = 4; - } - else - return false; - } - else return false; - - return true; -} - -#ifdef BOP_DEBUG -/** - * Implements operator <<. - */ -ostream &operator<<(ostream &stream, BOP_Face *f) -{ - char aux[20]; - BOP_stringTAG(f->m_tag,aux); - if (f->size()==3) { - stream << "Face[" << f->getVertex(0) << "," << f->getVertex(1) << ","; - stream << f->getVertex(2) << "] (" << aux << ") <-- " << f->m_originalFace; - } - else { - stream << "Face[" << f->getVertex(0) << "," << f->getVertex(1) << ","; - stream << f->getVertex(2) << "," << f->getVertex(3) << "] (" << aux; - stream << ") <-- " << f->m_originalFace; - } - - return stream; -} -#endif diff --git a/intern/boolop/intern/BOP_Face.h b/intern/boolop/intern/BOP_Face.h deleted file mode 100644 index 4f09618e23a..00000000000 --- a/intern/boolop/intern/BOP_Face.h +++ /dev/null @@ -1,120 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file boolop/intern/BOP_Face.h - * \ingroup boolopintern - */ - - -#ifndef __BOP_FACE_H__ -#define __BOP_FACE_H__ - -#include "BOP_Tag.h" -#include "MT_Plane3.h" -#include "BOP_Indexs.h" -#include "BOP_BBox.h" -#include "BOP_Misc.h" -#include <iostream> -#include <vector> - -class BOP_Face; - -typedef std::vector<BOP_Face *> BOP_Faces; -typedef std::vector<BOP_Face *>::iterator BOP_IT_Faces; - -class BOP_Face -{ -private: - BOP_TAG m_tag; - MT_Plane3 m_plane; - BOP_Index m_originalFace; - -protected: - BOP_Index m_indexs[4]; - unsigned int m_size; - unsigned int m_split; - BOP_BBox *m_bbox; - -public: - BOP_Face(MT_Plane3 plane, BOP_Index originalFace); - virtual ~BOP_Face(){if (m_bbox) delete m_bbox;}; - inline MT_Plane3 getPlane() const {return m_plane;}; - inline void setPlane(const MT_Plane3 plane) {m_plane = plane;}; - inline BOP_TAG getTAG() const {return m_tag;}; - inline void setTAG(const BOP_TAG t) {m_tag = t;}; - inline BOP_Index getOriginalFace() const {return m_originalFace;}; - inline void setOriginalFace(const BOP_Index originalFace) {m_originalFace=originalFace;}; - inline BOP_Index getVertex(unsigned int i) const {return m_indexs[i];}; - inline void setVertex(const BOP_Index idx, const BOP_Index i) {m_indexs[idx]=i;}; - inline unsigned int getSplit() const {return m_split;}; - inline void setSplit(const unsigned int i) {m_split=i;}; - - void invert(); - inline void setBBox(const MT_Point3& p1,const MT_Point3& p2,const MT_Point3& p3) { - m_bbox = new BOP_BBox(p1, p2, p3);}; - inline BOP_BBox *getBBox() {return m_bbox;}; - inline void freeBBox(){if (m_bbox!=NULL) {delete m_bbox; m_bbox=NULL;} }; - - inline unsigned int size() const {return m_size;}; - - virtual bool getEdgeIndex(BOP_Index v1, BOP_Index v2, unsigned int &e) = 0; - virtual void replaceVertexIndex(BOP_Index oldIndex, BOP_Index newIndex) = 0; - virtual bool containsVertex(BOP_Index v) = 0; - -#ifdef BOP_DEBUG - friend ostream &operator<<(ostream &stream, BOP_Face *f); -#endif -}; - -class BOP_Face3: public BOP_Face -{ -public: - BOP_Face3(BOP_Index i, BOP_Index j, BOP_Index k, MT_Plane3 p, BOP_Index originalFace); - bool getEdgeIndex(BOP_Index v1, BOP_Index v2, unsigned int &e); - void replaceVertexIndex(BOP_Index oldIndex, BOP_Index newIndex); - bool containsVertex(BOP_Index v); - - bool getNeighbours(BOP_Index v, BOP_Index &prev, BOP_Index &next); - bool getPreviousVertex(BOP_Index v, BOP_Index &w); - bool getNextVertex(BOP_Index v, BOP_Index &w); -}; - -class BOP_Face4: public BOP_Face -{ -public: - BOP_Face4(BOP_Index i, BOP_Index j, BOP_Index k, BOP_Index l, MT_Plane3 p, BOP_Index originalFace); - bool getEdgeIndex(BOP_Index v1, BOP_Index v2, unsigned int &e); - void replaceVertexIndex(BOP_Index oldIndex, BOP_Index newIndex); - bool containsVertex(BOP_Index v); - - bool getNeighbours(BOP_Index v, BOP_Index &prev, BOP_Index &next, BOP_Index &opp); - bool getPreviousVertex(BOP_Index v, BOP_Index &w); - bool getNextVertex(BOP_Index v, BOP_Index &w); - bool getOppositeVertex(BOP_Index v, BOP_Index &w); -}; - -#endif diff --git a/intern/boolop/intern/BOP_Face2Face.cpp b/intern/boolop/intern/BOP_Face2Face.cpp deleted file mode 100644 index 905d23fddff..00000000000 --- a/intern/boolop/intern/BOP_Face2Face.cpp +++ /dev/null @@ -1,1250 +0,0 @@ -/* - * - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): Marc Freixas, Ken Hughes - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file boolop/intern/BOP_Face2Face.cpp - * \ingroup boolopintern - */ - - -#include "BOP_Face2Face.h" -#include "BOP_BBox.h" - -// TAGS for segment classification in x-segment creation -// sA -> point of sA -// sB -> point of sB -// sX -> point of sA and SB -#define sA_sB 12 -#define sB_sA 21 -#define sX_sA 31 -#define sA_sX 13 -#define sX_sB 32 -#define sB_sX 23 -#define sX_sX 33 - -#define sA_sA_sB 112 -#define sB_sB_sA 221 -#define sB_sA_sA 211 -#define sA_sB_sB 122 -#define sA_sB_sA 121 -#define sB_sA_sB 212 -#define sA_sX_sB 132 -#define sB_sX_sA 231 -#define sX_sA_sB 312 -#define sX_sB_sA 321 -#define sA_sB_sX 123 -#define sB_sA_sX 213 - -#define sA_sA_sB_sB 1122 -#define sB_sB_sA_sA 2211 -#define sA_sB_sA_sB 1212 -#define sB_sA_sB_sA 2121 -#define sA_sB_sB_sA 1221 -#define sB_sA_sA_sB 2112 - -void BOP_intersectCoplanarFaces(BOP_Mesh* mesh, - BOP_Faces* facesB, - BOP_Face* faceA, - BOP_Face* faceB, - bool invert); - -void BOP_intersectCoplanarFaces(BOP_Mesh* mesh, - BOP_Faces* facesB, - BOP_Face* faceB, - BOP_Segment sA, - MT_Plane3 planeA, - bool invert); - -void BOP_intersectNonCoplanarFaces(BOP_Mesh* mesh, - BOP_Faces* facesA, - BOP_Faces* facesB, - BOP_Face* faceA, - BOP_Face* faceB); - -void BOP_getPoints(BOP_Mesh* mesh, - BOP_Face* faceA, - BOP_Segment& sA, - MT_Plane3 planeB, - MT_Point3* points, - unsigned int* faces, - unsigned int& size, - unsigned int faceValue); - -void BOP_mergeSort(MT_Point3 *points, unsigned int *face, unsigned int &size, bool &invertA, bool &invertB); - -void BOP_createXS(BOP_Mesh* mesh, - BOP_Face* faceA, - BOP_Face* faceB, - BOP_Segment sA, - BOP_Segment sB, - bool invert, - BOP_Segment* segments); - -void BOP_createXS(BOP_Mesh* mesh, - BOP_Face* faceA, - BOP_Face* faceB, - MT_Plane3 planeA, - MT_Plane3 planeB, - BOP_Segment sA, - BOP_Segment sB, - bool invert, - BOP_Segment* segments); - -BOP_Index BOP_getVertexIndex(BOP_Mesh* mesh, - MT_Point3 point, - unsigned int cfgA, - unsigned int cfgB, - BOP_Index vA, - BOP_Index vB, - bool invert); - -BOP_Index BOP_getVertexIndex(BOP_Mesh *mesh, MT_Point3 point, unsigned int cfg, BOP_Index v); - -void triangulate(BOP_Mesh *mesh, BOP_Faces *faces, BOP_Face *face, BOP_Segment s); - -BOP_Face *BOP_getOppositeFace(BOP_Mesh* mesh, - BOP_Faces* faces, - BOP_Face* face, - BOP_Edge* edge); - -bool BOP_overlap(MT_Vector3 normal, - MT_Point3 p1, - MT_Point3 p2, - MT_Point3 p3, - MT_Point3 q1, - MT_Point3 q2, - MT_Point3 q3); - -void BOP_mergeVertexs(BOP_Mesh *mesh, unsigned int firstFace); - - -/** - * Computes intersections between faces of both lists. - * @param mesh mesh that contains the faces, edges and vertices - * @param facesA set of faces from object A - * @param facesB set of faces from object B - * - * Two optimizations were added here: - * 1) keep the bounding box for a face once it's created; this is - * especially important for B faces, since they were being created and - * recreated over and over - * 2) associate a "split" index in the faceB vector with each A face; when - * an A face is split, we will not need to recheck any B faces have - * already been checked against that original A face - */ - -void BOP_Face2Face(BOP_Mesh *mesh, BOP_Faces *facesA, BOP_Faces *facesB) -{ - for(unsigned int idxFaceA=0;idxFaceA<facesA->size();idxFaceA++) { - BOP_Face *faceA = (*facesA)[idxFaceA]; - MT_Plane3 planeA = faceA->getPlane(); - MT_Point3 p1 = mesh->getVertex(faceA->getVertex(0))->getPoint(); - MT_Point3 p2 = mesh->getVertex(faceA->getVertex(1))->getPoint(); - MT_Point3 p3 = mesh->getVertex(faceA->getVertex(2))->getPoint(); - - /* get (or create) bounding box for face A */ - if( faceA->getBBox() == NULL ) - faceA->setBBox(p1,p2,p3); - BOP_BBox *boxA = faceA->getBBox(); - - /* start checking B faces with the previously stored split index */ - - for(unsigned int idxFaceB=faceA->getSplit(); - idxFaceB<facesB->size() && (faceA->getTAG() != BROKEN) && (faceA->getTAG() != PHANTOM);) { - BOP_Face *faceB = (*facesB)[idxFaceB]; - faceA->setSplit(idxFaceB); - if ((faceB->getTAG() != BROKEN) && (faceB->getTAG() != PHANTOM)) { - - /* get (or create) bounding box for face B */ - if( faceB->getBBox() == NULL ) { - faceB->setBBox(mesh->getVertex(faceB->getVertex(0))->getPoint(), - mesh->getVertex(faceB->getVertex(1))->getPoint(), - mesh->getVertex(faceB->getVertex(2))->getPoint()); - } - BOP_BBox *boxB = faceB->getBBox(); - - if (boxA->intersect(*boxB)) { - MT_Plane3 planeB = faceB->getPlane(); - if (BOP_containsPoint(planeB,p1) && - BOP_containsPoint(planeB,p2) && - BOP_containsPoint(planeB,p3)) - { - if (BOP_orientation(planeB,planeA)>0) { - BOP_intersectCoplanarFaces(mesh,facesB,faceA,faceB,false); - } - } - else { - BOP_intersectNonCoplanarFaces(mesh,facesA,facesB,faceA,faceB); - } - } - } - idxFaceB++; - } - } - - - // Clean broken faces from facesA - BOP_IT_Faces it; - it = facesA->begin(); - while (it != facesA->end()) { - BOP_Face *face = *it; - if (face->getTAG() == BROKEN) it = facesA->erase(it); - else it++; - } - /* - it = facesB->begin(); - while (it != facesB->end()) { - BOP_Face *face = *it; - if (face->getTAG() == BROKEN) it = facesB->erase(it); - else it++; - } - */ -} - -/** - * Computes intesections of coplanars faces from object A with faces from object B. - * @param mesh mesh that contains the faces, edges and vertices - * @param facesA set of faces from object A - * @param facesB set of faces from object B - */ -void BOP_sew(BOP_Mesh *mesh, BOP_Faces *facesA, BOP_Faces *facesB) -{ - for(unsigned int idxFaceB = 0; idxFaceB < facesB->size(); idxFaceB++) { - BOP_Face *faceB = (*facesB)[idxFaceB]; - MT_Plane3 planeB = faceB->getPlane(); - MT_Point3 p1 = mesh->getVertex(faceB->getVertex(0))->getPoint(); - MT_Point3 p2 = mesh->getVertex(faceB->getVertex(1))->getPoint(); - MT_Point3 p3 = mesh->getVertex(faceB->getVertex(2))->getPoint(); - - for(unsigned int idxFaceA = 0; - idxFaceA < facesA->size() && - faceB->getTAG() != BROKEN && - faceB->getTAG() != PHANTOM; - idxFaceA++) { - BOP_Face *faceA = (*facesA)[idxFaceA]; - if ((faceA->getTAG() != BROKEN)&&(faceA->getTAG() != PHANTOM)) { - MT_Plane3 planeA = faceA->getPlane(); - if (BOP_containsPoint(planeA,p1) && - BOP_containsPoint(planeA,p2) && - BOP_containsPoint(planeA,p3)) { - if (BOP_orientation(planeA,planeB) > 0) { - BOP_intersectCoplanarFaces(mesh,facesA,faceB,faceA,true); - } - } - } - } - } -} - -/** - * Triangulates faceB using edges of faceA that both are complanars. - * @param mesh mesh that contains the faces, edges and vertices - * @param facesB set of faces from object B - * @param faceA face from object A - * @param faceB face from object B - * @param invert indicates if faceA has priority over faceB - */ -void BOP_intersectCoplanarFaces(BOP_Mesh* mesh, - BOP_Faces* facesB, - BOP_Face* faceA, - BOP_Face* faceB, - bool invert) -{ - unsigned int oldSize = facesB->size(); - unsigned int originalFaceB = faceB->getOriginalFace(); - - MT_Point3 p1 = mesh->getVertex(faceA->getVertex(0))->getPoint(); - MT_Point3 p2 = mesh->getVertex(faceA->getVertex(1))->getPoint(); - MT_Point3 p3 = mesh->getVertex(faceA->getVertex(2))->getPoint(); - - MT_Vector3 normal(faceA->getPlane().x(),faceA->getPlane().y(),faceA->getPlane().z()); - - MT_Vector3 p1p2 = p2-p1; - - MT_Plane3 plane1((p1p2.cross(normal).normalized()),p1); - - BOP_Segment sA; - sA.m_cfg1 = BOP_Segment::createVertexCfg(1); - sA.m_v1 = faceA->getVertex(0); - sA.m_cfg2 = BOP_Segment::createVertexCfg(2); - sA.m_v2 = faceA->getVertex(1); - - BOP_intersectCoplanarFaces(mesh,facesB,faceB,sA,plane1,invert); - - MT_Vector3 p2p3 = p3-p2; - MT_Plane3 plane2((p2p3.cross(normal).normalized()),p2); - - sA.m_cfg1 = BOP_Segment::createVertexCfg(2); - sA.m_v1 = faceA->getVertex(1); - sA.m_cfg2 = BOP_Segment::createVertexCfg(3); - sA.m_v2 = faceA->getVertex(2); - - if (faceB->getTAG() == BROKEN) { - for(unsigned int idxFace = oldSize; idxFace < facesB->size(); idxFace++) { - BOP_Face *face = (*facesB)[idxFace]; - if (face->getTAG() != BROKEN && originalFaceB == face->getOriginalFace()) - BOP_intersectCoplanarFaces(mesh,facesB,face,sA,plane2,invert); - } - } - else { - BOP_intersectCoplanarFaces(mesh,facesB,faceB,sA,plane2,invert); - } - - MT_Vector3 p3p1 = p1-p3; - MT_Plane3 plane3((p3p1.cross(normal).safe_normalized()),p3); - - sA.m_cfg1 = BOP_Segment::createVertexCfg(3); - sA.m_v1 = faceA->getVertex(2); - sA.m_cfg2 = BOP_Segment::createVertexCfg(1); - sA.m_v2 = faceA->getVertex(0); - - if (faceB->getTAG() == BROKEN) { - for(unsigned int idxFace = oldSize; idxFace < facesB->size(); idxFace++) { - BOP_Face *face = (*facesB)[idxFace]; - if (face->getTAG() != BROKEN && originalFaceB == face->getOriginalFace()) - BOP_intersectCoplanarFaces(mesh,facesB,face,sA,plane3,invert); - } - } - else { - BOP_intersectCoplanarFaces(mesh,facesB,faceB,sA,plane3,invert); - } -} - -/** - * Triangulates faceB using segment sA and planeA. - * @param mesh mesh that contains the faces, edges and vertices - * @param facesB set of faces from object B - * @param faceB face from object B - * @param sA segment to intersect with faceB - * @param planeA plane to intersect with faceB - * @param invert indicates if sA has priority over faceB - */ -void BOP_intersectCoplanarFaces(BOP_Mesh* mesh, - BOP_Faces* facesB, - BOP_Face* faceB, - BOP_Segment sA, - MT_Plane3 planeA, - bool invert) -{ - BOP_Segment sB = BOP_splitFace(planeA,mesh,faceB); - - if (BOP_Segment::isDefined(sB.m_cfg1)) { - BOP_Segment xSegment[2]; - BOP_createXS(mesh,NULL,faceB,planeA,MT_Plane3(),sA,sB,invert,xSegment); - if (BOP_Segment::isDefined(xSegment[1].m_cfg1)) { - unsigned int sizefaces = mesh->getNumFaces(); - triangulate(mesh,facesB,faceB,xSegment[1]); - BOP_mergeVertexs(mesh,sizefaces); - } - } -} - -/** - * Triangulates faceB using edges of faceA that both are not complanars. - * @param mesh mesh that contains the faces, edges and vertices - * @param facesB set of faces from object B - * @param faceA face from object A - * @param faceB face from object B - */ -void BOP_intersectNonCoplanarFaces(BOP_Mesh *mesh, - BOP_Faces *facesA, - BOP_Faces *facesB, - BOP_Face *faceA, - BOP_Face *faceB) -{ - // Obtain segments of faces A and B from the intersection with their planes - BOP_Segment sA = BOP_splitFace(faceB->getPlane(),mesh,faceA); - BOP_Segment sB = BOP_splitFace(faceA->getPlane(),mesh,faceB); - - if (BOP_Segment::isDefined(sA.m_cfg1) && BOP_Segment::isDefined(sB.m_cfg1)) { - // There is an intesection, build the X-segment - BOP_Segment xSegment[2]; - BOP_createXS(mesh,faceA,faceB,sA,sB,false,xSegment); - - unsigned int sizefaces = mesh->getNumFaces(); - triangulate(mesh,facesA,faceA,xSegment[0]); - BOP_mergeVertexs(mesh,sizefaces); - - sizefaces = mesh->getNumFaces(); - triangulate(mesh,facesB,faceB,xSegment[1]); - BOP_mergeVertexs(mesh,sizefaces); - } -} - -/** - * Tests if faces since firstFace have all vertexs non-coincident of colinear, otherwise repairs the mesh. - * @param mesh mesh that contains the faces, edges and vertices - * @param firstFace first face index to be tested - */ -void BOP_mergeVertexs(BOP_Mesh *mesh, unsigned int firstFace) -{ - unsigned int numFaces = mesh->getNumFaces(); - for(unsigned int idxFace = firstFace; idxFace < numFaces; idxFace++) { - BOP_Face *face = mesh->getFace(idxFace); - if ((face->getTAG() != BROKEN) && (face->getTAG() != PHANTOM)) { - MT_Point3 vertex1 = mesh->getVertex(face->getVertex(0))->getPoint(); - MT_Point3 vertex2 = mesh->getVertex(face->getVertex(1))->getPoint(); - MT_Point3 vertex3 = mesh->getVertex(face->getVertex(2))->getPoint(); - if (BOP_collinear(vertex1,vertex2,vertex3)) // collinear triangle - face->setTAG(PHANTOM); - } - } -} - -/** - * Obtains the points of the segment created from the intersection between faceA and planeB. - * @param mesh mesh that contains the faces, edges and vertices - * @param faceA intersected face - * @param sA segment of the intersection between faceA and planeB - * @param planeB intersected plane - * @param points array of points where the new points are saved - * @param faces array of relative face index to the points - * @param size size of arrays points and faces - * @param faceValue relative face index of new points - */ -void BOP_getPoints(BOP_Mesh* mesh, - BOP_Face* faceA, - BOP_Segment& sA, - MT_Plane3 planeB, - MT_Point3* points, - unsigned int* faces, - unsigned int& size, - unsigned int faceValue) -{ - MT_Point3 p1,p2; - - if (BOP_Segment::isDefined(sA.m_cfg1)) { - if (BOP_Segment::isEdge(sA.m_cfg1)) { - // the new point becomes of split faceA edge - p1 = BOP_splitEdge(planeB,mesh,faceA,BOP_Segment::getEdge(sA.m_cfg1)); - } - else if (BOP_Segment::isVertex(sA.m_cfg1)) { - // the new point becomes of vertex faceA - p1 = mesh->getVertex(BOP_Segment::getVertex(sA.m_v1))->getPoint(); - } - - if (BOP_Segment::isDefined(sA.m_cfg2)) { - if (BOP_Segment::isEdge(sA.m_cfg2)) { - p2 = BOP_splitEdge(planeB,mesh,faceA,BOP_Segment::getEdge(sA.m_cfg2)); - } - else if (BOP_Segment::isVertex(sA.m_cfg2)) { - p2 = mesh->getVertex(BOP_Segment::getVertex(sA.m_v2))->getPoint(); - } - points[size] = p1; - points[size+1] = p2; - faces[size] = faceValue; - faces[size+1] = faceValue; - size += 2; - } - - else { - points[size] = p1; - faces[size] = faceValue; - size++; - } - } -} - -/** - * Sorts the colinear points and relative face indices. - * @param points array of points where the new points are saved - * @param faces array of relative face index to the points - * @param size size of arrays points and faces - * @param invertA indicates if points of same relative face had been exchanged - */ -void BOP_mergeSort(MT_Point3 *points, unsigned int *face, unsigned int &size, bool &invertA, bool &invertB) { - MT_Point3 sortedPoints[4]; - unsigned int sortedFaces[4], position[4]; - unsigned int i; - if (size == 2) { - - // Trivial case, only test the merge ... - if (BOP_fuzzyZero(points[0].distance(points[1]))) { - face[0] = 3; - size--; - } - } - else { - // size is 3 or 4 - // Get segment extreme points - MT_Scalar maxDistance = -1; - for(i=0;i<size-1;i++){ - for(unsigned int j=i+1;j<size;j++){ - MT_Scalar distance = points[i].distance(points[j]); - if (distance > maxDistance){ - maxDistance = distance; - position[0] = i; - position[size-1] = j; - } - } - } - - // Get segment inner points - position[1] = position[2] = size; - for(i=0;i<size;i++){ - if ((i != position[0]) && (i != position[size-1])){ - if (position[1] == size) position[1] = i; - else position[2] = i; - } - } - - // Get inner points - if (position[2] < size) { - MT_Scalar d1 = points[position[1]].distance(points[position[0]]); - MT_Scalar d2 = points[position[2]].distance(points[position[0]]); - if (d1 > d2) { - unsigned int aux = position[1]; - position[1] = position[2]; - position[2] = aux; - } - } - - // Sort data - for(i=0;i<size;i++) { - sortedPoints[i] = points[position[i]]; - sortedFaces[i] = face[position[i]]; - } - - invertA = false; - invertB = false; - if (face[1] == 1) { - - // invertA? - for(i=0;i<size;i++) { - if (position[i] == 1) { - invertA = true; - break; - } - else if (position[i] == 0) break; - } - - // invertB? - if (size == 4) { - for(i=0;i<size;i++) { - if (position[i] == 3) { - invertB = true; - break; - } - else if (position[i] == 2) break; - } - } - } - else if (face[1] == 2) { - // invertB? - for(i=0;i<size;i++) { - if (position[i] == 2) { - invertB = true; - break; - } - else if (position[i] == 1) break; - } - } - - - // Merge data - MT_Scalar d1 = sortedPoints[1].distance(sortedPoints[0]); - MT_Scalar d2 = sortedPoints[1].distance(sortedPoints[2]); - if (BOP_fuzzyZero(d1) && sortedFaces[1] != sortedFaces[0]) { - if (BOP_fuzzyZero(d2) && sortedFaces[1] != sortedFaces[2]) { - if (d1 < d2) { - // merge 0 and 1 - sortedFaces[0] = 3; - for(i = 1; i<size-1;i++) { - sortedPoints[i] = sortedPoints[i+1]; - sortedFaces[i] = sortedFaces[i+1]; - } - size--; - if (size == 3) { - // merge 1 and 2 ??? - d1 = sortedPoints[1].distance(sortedPoints[2]); - if (BOP_fuzzyZero(d1) && sortedFaces[1] != sortedFaces[2]) { - // merge! - sortedFaces[1] = 3; - size--; - } - } - } - else { - // merge 1 and 2 - sortedFaces[1] = 3; - for(i = 2; i<size-1;i++) { - sortedPoints[i] = sortedPoints[i+1]; - sortedFaces[i] = sortedFaces[i+1]; - } - size--; - } - } - else { - // merge 0 and 1 - sortedFaces[0] = 3; - for(i = 1; i<size-1;i++) { - sortedPoints[i] = sortedPoints[i+1]; - sortedFaces[i] = sortedFaces[i+1]; - } - size--; - if (size == 3) { - // merge 1 i 2 ??? - d1 = sortedPoints[1].distance(sortedPoints[2]); - if (BOP_fuzzyZero(d1) && sortedFaces[1] != sortedFaces[2]) { - // merge! - sortedFaces[1] = 3; - size--; - } - } - } - } - else { - if (BOP_fuzzyZero(d2) && sortedFaces[1] != sortedFaces[2]) { - // merge 1 and 2 - sortedFaces[1] = 3; - for(i = 2; i<size-1;i++) { - sortedPoints[i] = sortedPoints[i+1]; - sortedFaces[i] = sortedFaces[i+1]; - } - size--; - } - else if (size == 4) { - d1 = sortedPoints[2].distance(sortedPoints[3]); - if (BOP_fuzzyZero(d1) && sortedFaces[2] != sortedFaces[3]) { - // merge 2 and 3 - sortedFaces[2] = 3; - size--; - } - } - } - - // Merge initial points ... - for(i=0;i<size;i++) { - points[i] = sortedPoints[i]; - face[i] = sortedFaces[i]; - } - - } -} - - -/** - * Computes the x-segment of two segments (the shared interval). The segments needs to have sA.m_cfg1 > 0 && sB.m_cfg1 > 0 . - * @param mesh mesh that contains the faces, edges and vertices - * @param faceA face of object A - * @param faceB face of object B - * @param sA segment of intersection between faceA and planeB - * @param sB segment of intersection between faceB and planeA - * @param invert indicates if faceA has priority over faceB - * @param segmemts array of the output x-segments - */ -void BOP_createXS(BOP_Mesh* mesh, - BOP_Face* faceA, - BOP_Face* faceB, - BOP_Segment sA, - BOP_Segment sB, - bool invert, - BOP_Segment* segments) { - BOP_createXS(mesh, faceA, faceB, faceA->getPlane(), faceB->getPlane(), - sA, sB, invert, segments); -} - -/** - * Computes the x-segment of two segments (the shared interval). The segments needs to have sA.m_cfg1 > 0 && sB.m_cfg1 > 0 . - * @param mesh mesh that contains the faces, edges and vertices - * @param faceA face of object A - * @param faceB face of object B - * @param planeA plane of faceA - * @param planeB plane of faceB - * @param sA segment of intersection between faceA and planeB - * @param sB segment of intersection between faceB and planeA - * @param invert indicates if faceA has priority over faceB - * @param segmemts array of the output x-segments - */ -void BOP_createXS(BOP_Mesh* mesh, - BOP_Face* faceA, - BOP_Face* faceB, - MT_Plane3 planeA, - MT_Plane3 planeB, - BOP_Segment sA, - BOP_Segment sB, - bool invert, - BOP_Segment* segments) -{ - MT_Point3 points[4]; // points of the segments - unsigned int face[4]; // relative face indexs (1 => faceA, 2 => faceB) - unsigned int size = 0; // size of points and relative face indexs - - BOP_getPoints(mesh, faceA, sA, planeB, points, face, size, 1); - BOP_getPoints(mesh, faceB, sB, planeA, points, face, size, 2); - - bool invertA = false; - bool invertB = false; - BOP_mergeSort(points,face,size,invertA,invertB); - - if (invertA) sA.invert(); - if (invertB) sB.invert(); - - // Compute the configuration label - unsigned int label = 0; - for(unsigned int i =0; i < size; i++) { - label = face[i]+label*10; - } - - if (size == 1) { - // Two coincident points - segments[0].m_cfg1 = sA.m_cfg1; - segments[1].m_cfg1 = sB.m_cfg1; - - segments[0].m_v1 = BOP_getVertexIndex(mesh, points[0], sA.m_cfg1, sB.m_cfg1, - sA.m_v1, sB.m_v1, invert); - segments[1].m_v1 = segments[0].m_v1; - segments[0].m_cfg2 = segments[1].m_cfg2 = BOP_Segment::createUndefinedCfg(); - } - else if (size == 2) { - switch(label) { - // Two non-coincident points - case sA_sB: - case sB_sA: - segments[0].m_cfg1 = - segments[1].m_cfg1 = - segments[0].m_cfg2 = - segments[1].m_cfg2 = BOP_Segment::createUndefinedCfg(); - break; - - // Two coincident points and one non-coincident of sA - case sA_sX: - segments[0].m_cfg1 = sA.m_cfg2; - segments[1].m_cfg1 = sB.m_cfg1; - segments[0].m_v1 = BOP_getVertexIndex(mesh, points[1], sA.m_cfg2, sB.m_cfg1, - sA.m_v2, sB.m_v1, invert); - segments[1].m_v1 = segments[0].m_v1; - - segments[0].m_cfg2 = BOP_Segment::createUndefinedCfg(); - segments[1].m_cfg2 = BOP_Segment::createUndefinedCfg(); - break; - case sX_sA: - segments[0].m_cfg1 = sA.m_cfg1; - segments[1].m_cfg1 = sB.m_cfg1; - segments[0].m_v1 = BOP_getVertexIndex(mesh, points[0], sA.m_cfg1, sB.m_cfg1, - sA.m_v1, sB.m_v1, invert); - segments[1].m_v1 = segments[0].m_v1; - - segments[0].m_cfg2 = BOP_Segment::createUndefinedCfg(); - segments[1].m_cfg2 = BOP_Segment::createUndefinedCfg(); - break; - - // Two coincident points and one non-coincident of sB - case sB_sX: - segments[0].m_cfg1 = sA.m_cfg1; - segments[1].m_cfg1 = sB.m_cfg2; - segments[0].m_v1 = BOP_getVertexIndex(mesh, points[1], sA.m_cfg1, sB.m_cfg2, - sA.m_v1, sB.m_v2, invert); - segments[1].m_v1 = segments[0].m_v1; - - segments[0].m_cfg2 = BOP_Segment::createUndefinedCfg(); - segments[1].m_cfg2 = BOP_Segment::createUndefinedCfg(); - break; - case sX_sB: - segments[0].m_cfg1 = sA.m_cfg1; - segments[1].m_cfg1 = sB.m_cfg1; - segments[0].m_v1 = BOP_getVertexIndex(mesh, points[0], sA.m_cfg1, sB.m_cfg1, - sA.m_v1, sB.m_v1, invert); - segments[1].m_v1 = segments[0].m_v1; - - segments[0].m_cfg2 = BOP_Segment::createUndefinedCfg(); - segments[1].m_cfg2 = BOP_Segment::createUndefinedCfg(); - break; - - // coincident points 2-2 - case sX_sX: - segments[0].m_cfg1 = sA.m_cfg1; - segments[1].m_cfg1 = sB.m_cfg1; - segments[0].m_v1 = BOP_getVertexIndex(mesh, points[0], sA.m_cfg1, sB.m_cfg1, - sA.m_v1, sB.m_v1, invert); - segments[1].m_v1 = segments[0].m_v1; - - segments[0].m_cfg2 = sA.m_cfg2; - segments[1].m_cfg2 = sB.m_cfg2; - segments[0].m_v2 = BOP_getVertexIndex(mesh, points[1], sA.m_cfg2, sB.m_cfg2, - sA.m_v2, sB.m_v2, invert); - segments[1].m_v2 = segments[0].m_v2; - break; - - default: - break; - } - } - else if (size == 3) { - switch(label) { - case sA_sA_sB: - case sB_sA_sA: - case sA_sB_sB: - case sB_sB_sA: - segments[0].m_cfg1 = - segments[1].m_cfg1 = - segments[0].m_cfg2 = - segments[1].m_cfg2 = BOP_Segment::createUndefinedCfg(); - break; - - case sA_sB_sA: - segments[1].m_v1 = BOP_getVertexIndex(mesh,points[1],sB.m_cfg1,sB.m_v1); - segments[1].m_cfg1 = sB.m_cfg1; - segments[1].m_cfg2 = BOP_Segment::createUndefinedCfg(); - segments[0].m_cfg1 = sA.getConfig(); - segments[0].m_cfg2 = BOP_Segment::createUndefinedCfg(); - segments[0].m_v1 = segments[1].m_v1; - break; - - case sB_sA_sB: - segments[0].m_v1 = BOP_getVertexIndex(mesh,points[1],sA.m_cfg1,sA.m_v1); - segments[0].m_cfg1 = sA.m_cfg1; - segments[0].m_cfg2 = BOP_Segment::createUndefinedCfg(); - segments[1].m_cfg1 = sB.getConfig(); - segments[1].m_cfg2 = BOP_Segment::createUndefinedCfg(); - segments[1].m_v1 = segments[0].m_v1; - break; - - case sA_sX_sB: - segments[0].m_cfg1 = sA.m_cfg2; - segments[1].m_cfg1 = sB.m_cfg1; - segments[0].m_v1 = BOP_getVertexIndex(mesh, points[1], sA.m_cfg2, sB.m_cfg1, - sA.m_v2, sB.m_v1, invert); - segments[1].m_v1 = segments[0].m_v1; - segments[0].m_cfg2 = BOP_Segment::createUndefinedCfg(); - segments[1].m_cfg2 = BOP_Segment::createUndefinedCfg(); - break; - - case sB_sX_sA: - segments[0].m_cfg1 = sA.m_cfg1; - segments[1].m_cfg1 = sB.m_cfg2; - segments[0].m_v1 = BOP_getVertexIndex(mesh, points[1], sA.m_cfg1, sB.m_cfg2, - sA.m_v1, sB.m_v2, invert); - segments[1].m_v1 = segments[0].m_v1; - segments[0].m_cfg2 = BOP_Segment::createUndefinedCfg(); - segments[1].m_cfg2 = BOP_Segment::createUndefinedCfg(); - break; - - case sX_sA_sB: - segments[0].m_cfg1 = sA.m_cfg1; - segments[1].m_cfg1 = sB.m_cfg1; - segments[0].m_v1 = BOP_getVertexIndex(mesh, points[0], sA.m_cfg1, sB.m_cfg1, - sA.m_v1, sB.m_v1, invert); - segments[1].m_v1 = segments[0].m_v1; - - segments[0].m_cfg2 = sA.m_cfg2; - segments[1].m_cfg2 = sB.getConfig(); - segments[0].m_v2 = BOP_getVertexIndex(mesh, points[1], sA.m_cfg2, sA.m_v2); - segments[1].m_v2 = segments[0].m_v2; - break; - - case sX_sB_sA: - segments[0].m_cfg1 = sA.m_cfg1; - segments[1].m_cfg1 = sB.m_cfg1; - segments[0].m_v1 = BOP_getVertexIndex(mesh, points[0], sA.m_cfg1, sB.m_cfg1, - sA.m_v1, sB.m_v1, invert); - segments[1].m_v1 = segments[0].m_v1; - - segments[0].m_cfg2 = sA.getConfig(); - segments[1].m_cfg2 = sB.m_cfg2; - segments[0].m_v2 = BOP_getVertexIndex(mesh,points[1],sB.m_cfg2,sB.m_v2); - segments[1].m_v2 = segments[0].m_v2; - break; - - case sA_sB_sX: - segments[0].m_cfg1 = sA.getConfig(); - segments[1].m_cfg1 = sB.m_cfg1; - segments[0].m_v1 = BOP_getVertexIndex(mesh,points[1],sB.m_cfg1,sB.m_v1); - segments[1].m_v1 = segments[0].m_v1; - - segments[0].m_cfg2 = sA.m_cfg2; - segments[1].m_cfg2 = sB.m_cfg2; - segments[0].m_v2 = BOP_getVertexIndex(mesh, points[2], sA.m_cfg2, sB.m_cfg2, - sA.m_v2, sB.m_v2, invert); - segments[1].m_v2 = segments[0].m_v2; - break; - - case sB_sA_sX: - segments[0].m_cfg1 = sA.m_cfg1; - segments[1].m_cfg1 = sB.getConfig(); - segments[0].m_v1 = BOP_getVertexIndex(mesh,points[1],sA.m_cfg1,sA.m_v1); - segments[1].m_v1 = segments[0].m_v1; - - segments[0].m_cfg2 = sA.m_cfg2; - segments[1].m_cfg2 = sB.m_cfg2; - segments[0].m_v2 = BOP_getVertexIndex(mesh, points[2], sA.m_cfg2, sB.m_cfg2, - sA.m_v2, sB.m_v2, invert); - segments[1].m_v2 = segments[0].m_v2; - break; - - default: - break; - } - } - else { - // 4! - switch(label) { - case sA_sA_sB_sB: - case sB_sB_sA_sA: - segments[0].m_cfg1 = - segments[1].m_cfg1 = - segments[0].m_cfg2 = - segments[1].m_cfg2 = BOP_Segment::createUndefinedCfg(); - break; - - case sA_sB_sA_sB: - segments[0].m_cfg1 = sA.getConfig(); - segments[1].m_cfg1 = sB.m_cfg1; - segments[0].m_v1 = BOP_getVertexIndex(mesh,points[1],sB.m_cfg1,sB.m_v1); - segments[1].m_v1 = segments[0].m_v1; - - segments[0].m_cfg2 = sA.m_cfg2; - segments[1].m_cfg2 = sB.getConfig(); - segments[0].m_v2 = BOP_getVertexIndex(mesh,points[2],sA.m_cfg2,sA.m_v2); - segments[1].m_v2 = segments[0].m_v2; - break; - - case sB_sA_sB_sA: - segments[0].m_cfg1 = sA.m_cfg1; - segments[1].m_cfg1 = sB.getConfig(); - segments[0].m_v1 = BOP_getVertexIndex(mesh,points[1],sA.m_cfg1,sA.m_v1); - segments[1].m_v1 = segments[0].m_v1; - - segments[0].m_cfg2 = sA.getConfig(); - segments[1].m_cfg2 = sB.m_cfg2; - segments[0].m_v2 = BOP_getVertexIndex(mesh,points[2],sB.m_cfg2,sB.m_v2); - segments[1].m_v2 = segments[0].m_v2; - break; - - case sA_sB_sB_sA: - segments[0].m_cfg1 = sA.getConfig(); - segments[1].m_cfg1 = sB.m_cfg1; - segments[0].m_v1 = BOP_getVertexIndex(mesh,points[1],sB.m_cfg1,sB.m_v1); - segments[1].m_v1 = segments[0].m_v1; - - segments[0].m_cfg2 = segments[0].m_cfg1; - segments[1].m_cfg2 = sB.m_cfg2; - segments[0].m_v2 = BOP_getVertexIndex(mesh,points[2],sB.m_cfg2,sB.m_v2); - segments[1].m_v2 = segments[0].m_v2; - break; - - case sB_sA_sA_sB: - segments[0].m_cfg1 = sA.m_cfg1; - segments[1].m_cfg1 = sB.getConfig(); - segments[0].m_v1 = BOP_getVertexIndex(mesh,points[1],sA.m_cfg1,sA.m_v1); - segments[1].m_v1 = segments[0].m_v1; - - segments[0].m_cfg2 = sA.m_cfg2; - segments[1].m_cfg2 = segments[1].m_cfg1; - segments[0].m_v2 = BOP_getVertexIndex(mesh,points[2],sA.m_cfg2,sA.m_v2); - segments[1].m_v2 = segments[0].m_v2; - break; - - default: - break; - } - } - - segments[0].sort(); - segments[1].sort(); -} - -/** - * Computes the vertex index of a point. - * @param mesh mesh that contains the faces, edges and vertices - * @param point input point - * @param cfgA configuration of point on faceA - * @param cfgB configuration of point on faceB - * @param vA vertex index of point on faceA - * @param vB vertex index of point on faceB - * @param invert indicates if vA has priority over vB - * @return final vertex index in the mesh - */ -BOP_Index BOP_getVertexIndex(BOP_Mesh* mesh, - MT_Point3 point, - unsigned int cfgA, - unsigned int cfgB, - BOP_Index vA, - BOP_Index vB, - bool invert) -{ - if (BOP_Segment::isVertex(cfgA)) { // exists vertex index on A - if (BOP_Segment::isVertex(cfgB)) { // exists vertex index on B - // unify vertex indexs - if (invert) - return mesh->replaceVertexIndex(vA,vB); - else - return mesh->replaceVertexIndex(vB,vA); - } - else - return vA; - } - else {// does not exist vertex index on A - if (BOP_Segment::isVertex(cfgB)) // exists vertex index on B - return vB; - else {// does not exist vertex index on B - return mesh->addVertex(point); - } - } -} - -/** - * Computes the vertex index of a point. - * @param mesh mesh that contains the faces, edges and vertices - * @param cfg configuration of point - * @param v vertex index of point - * @return final vertex index in the mesh - */ -BOP_Index BOP_getVertexIndex(BOP_Mesh *mesh, MT_Point3 point, unsigned int cfg, BOP_Index v) -{ - if (BOP_Segment::isVertex(cfg)) // vertex existent - return v; - else { - return mesh->addVertex(point); - } -} - -/******************************************************************************/ -/*** TRIANGULATE ***/ -/******************************************************************************/ - -/** - * Triangulates the input face according to the specified segment. - * @param mesh mesh that contains the faces, edges and vertices - * @param faces set of faces that contains the original face and the new triangulated faces - * @param face face to be triangulated - * @param s segment used to triangulate face - */ -void triangulate(BOP_Mesh *mesh, BOP_Faces *faces, BOP_Face *face, BOP_Segment s) -{ - if (BOP_Segment::isUndefined(s.m_cfg1)) { - // Nothing to do - } - else if (BOP_Segment::isVertex(s.m_cfg1)) { - // VERTEX(v1) + VERTEX(v2) => nothing to do - } - else if (BOP_Segment::isEdge(s.m_cfg1)) { - if (BOP_Segment::isVertex(s.m_cfg2) || BOP_Segment::isUndefined(s.m_cfg2)) { - // EDGE(v1) + VERTEX(v2) - BOP_Edge *edge = mesh->getEdge(face,BOP_Segment::getEdge(s.m_cfg1)); - BOP_triangulateA(mesh,faces,face,s.m_v1,BOP_Segment::getEdge(s.m_cfg1)); - BOP_Face *opposite = BOP_getOppositeFace(mesh,faces,face,edge); - if (opposite != NULL) { - unsigned int e; - opposite->getEdgeIndex(edge->getVertex1(), edge->getVertex2(),e); - BOP_triangulateA(mesh, faces, opposite, s.m_v1, e); - } - } - else { - // EDGE(v1) + EDGE(v2) - if (BOP_Segment::getEdge(s.m_cfg1) == BOP_Segment::getEdge(s.m_cfg2)) { - // EDGE(v1) == EDGE(v2) - BOP_Edge *edge = mesh->getEdge(face,BOP_Segment::getEdge(s.m_cfg1)); - BOP_triangulateD(mesh, faces, face, s.m_v1, s.m_v2, - BOP_Segment::getEdge(s.m_cfg1)); - BOP_Face *opposite = BOP_getOppositeFace(mesh,faces,face,edge); - if (opposite != NULL) { - unsigned int e; - opposite->getEdgeIndex(edge->getVertex1(), edge->getVertex2(),e); - BOP_triangulateD(mesh, faces, opposite, s.m_v1, s.m_v2, e); - } - } - else { // EDGE(v1) != EDGE(v2) - BOP_Edge *edge1 = mesh->getEdge(face,BOP_Segment::getEdge(s.m_cfg1)); - BOP_Edge *edge2 = mesh->getEdge(face,BOP_Segment::getEdge(s.m_cfg2)); - BOP_triangulateE(mesh, faces, face, s.m_v1, s.m_v2, - BOP_Segment::getEdge(s.m_cfg1), - BOP_Segment::getEdge(s.m_cfg2)); - BOP_Face *opposite = BOP_getOppositeFace(mesh,faces,face,edge1); - if (opposite != NULL) { - unsigned int e; - opposite->getEdgeIndex(edge1->getVertex1(), edge1->getVertex2(),e); - BOP_triangulateA(mesh, faces, opposite, s.m_v1, e); - } - opposite = BOP_getOppositeFace(mesh,faces,face,edge2); - if (opposite != NULL) { - unsigned int e; - opposite->getEdgeIndex(edge2->getVertex1(), edge2->getVertex2(),e); - BOP_triangulateA(mesh, faces, opposite, s.m_v2, e); - } - } - } - } - else if (BOP_Segment::isIn(s.m_cfg1)) { - if (BOP_Segment::isVertex(s.m_cfg2) || BOP_Segment::isUndefined(s.m_cfg2)) { - // IN(v1) + VERTEX(v2) - BOP_triangulateB(mesh,faces,face,s.m_v1); - } - else if (BOP_Segment::isEdge(s.m_cfg2)) { - // IN(v1) + EDGE(v2) - BOP_Edge *edge = mesh->getEdge(face,BOP_Segment::getEdge(s.m_cfg2)); - BOP_triangulateF(mesh,faces,face,s.m_v1,s.m_v2,BOP_Segment::getEdge(s.m_cfg2)); - BOP_Face *opposite = BOP_getOppositeFace(mesh,faces,face,edge); - if (opposite != NULL) { - unsigned int e; - opposite->getEdgeIndex(edge->getVertex1(), edge->getVertex2(),e); - BOP_triangulateA(mesh, faces, opposite, s.m_v2, e); - } - } - else // IN(v1) + IN(v2) - BOP_triangulateC(mesh,faces,face,s.m_v1,s.m_v2); - } -} - -/** - * Returns if a face is in the set of faces. - * @param faces set of faces - * @param face face to be searched - * @return if the face is inside faces - */ -bool BOP_containsFace(BOP_Faces *faces, BOP_Face *face) -{ - const BOP_IT_Faces facesEnd = faces->end(); - for(BOP_IT_Faces it=faces->begin();it!=facesEnd;it++) - { - if (*it == face) - return true; - } - - return false; -} - -/** - * Returns the first face of faces that shares the input edge of face. - * @param mesh mesh that contains the faces, edges and vertices - * @param faces set of faces - * @param face input face - * @param edge face's edge - * @return first face that shares the edge of input face - */ -BOP_Face *BOP_getOppositeFace(BOP_Mesh* mesh, - BOP_Faces* faces, - BOP_Face* face, - BOP_Edge* edge) -{ - if (edge == NULL) - return NULL; - - BOP_Indexs auxfaces = edge->getFaces(); - const BOP_IT_Indexs auxfacesEnd = auxfaces.end(); - for(BOP_IT_Indexs it = auxfaces.begin(); it != auxfacesEnd; it++) { - BOP_Face *auxface = mesh->getFace(*it); - if ((auxface != face) && (auxface->getTAG()!=BROKEN) && - BOP_containsFace(faces,auxface)) { - return auxface; - } - } - - return NULL; -} - -/******************************************************************************/ -/*** OVERLAPPING ***/ -/******************************************************************************/ - -/** - * Removes faces from facesB that are overlapped with anyone from facesA. - * @param mesh mesh that contains the faces, edges and vertices - * @param facesA set of faces from object A - * @param facesB set of faces from object B - */ -void BOP_removeOverlappedFaces(BOP_Mesh *mesh, BOP_Faces *facesA, BOP_Faces *facesB) -{ - for(unsigned int i=0;i<facesA->size();i++) { - BOP_Face *faceI = (*facesA)[i]; - if (faceI->getTAG()==BROKEN) continue; - bool overlapped = false; - MT_Point3 p1 = mesh->getVertex(faceI->getVertex(0))->getPoint(); - MT_Point3 p2 = mesh->getVertex(faceI->getVertex(1))->getPoint(); - MT_Point3 p3 = mesh->getVertex(faceI->getVertex(2))->getPoint(); - for(unsigned int j=0;j<facesB->size();) { - BOP_Face *faceJ = (*facesB)[j]; - if (faceJ->getTAG()!=BROKEN) { - MT_Plane3 planeJ = faceJ->getPlane(); - if (BOP_containsPoint(planeJ,p1) && BOP_containsPoint(planeJ,p2) - && BOP_containsPoint(planeJ,p3)) - { - MT_Point3 q1 = mesh->getVertex(faceJ->getVertex(0))->getPoint(); - MT_Point3 q2 = mesh->getVertex(faceJ->getVertex(1))->getPoint(); - MT_Point3 q3 = mesh->getVertex(faceJ->getVertex(2))->getPoint(); - if (BOP_overlap(MT_Vector3(planeJ.x(),planeJ.y(),planeJ.z()), - p1,p2,p3,q1,q2,q3)) - { - facesB->erase(facesB->begin()+j,facesB->begin()+(j+1)); - faceJ->setTAG(BROKEN); - overlapped = true; - } - else j++; - } - else j++; - }else j++; - } - if (overlapped) faceI->setTAG(OVERLAPPED); - } -} - -/** - * Computes if triangle p1,p2,p3 is overlapped with triangle q1,q2,q3. - * @param normal normal of the triangle p1,p2,p3 - * @param p1 point of first triangle - * @param p2 point of first triangle - * @param p3 point of first triangle - * @param q1 point of second triangle - * @param q2 point of second triangle - * @param q3 point of second triangle - * @return if there is overlapping between both triangles - */ -bool BOP_overlap(MT_Vector3 normal, MT_Point3 p1, MT_Point3 p2, MT_Point3 p3, - MT_Point3 q1, MT_Point3 q2, MT_Point3 q3) -{ - MT_Vector3 p1p2 = p2-p1; - MT_Plane3 plane1(p1p2.cross(normal),p1); - - MT_Vector3 p2p3 = p3-p2; - MT_Plane3 plane2(p2p3.cross(normal),p2); - - MT_Vector3 p3p1 = p1-p3; - MT_Plane3 plane3(p3p1.cross(normal),p3); - - BOP_TAG tag1 = BOP_createTAG(BOP_classify(q1,plane1)); - BOP_TAG tag2 = BOP_createTAG(BOP_classify(q1,plane2)); - BOP_TAG tag3 = BOP_createTAG(BOP_classify(q1,plane3)); - BOP_TAG tagQ1 = BOP_createTAG(tag1,tag2,tag3); - if (tagQ1 == IN_IN_IN) return true; - - tag1 = BOP_createTAG(BOP_classify(q2,plane1)); - tag2 = BOP_createTAG(BOP_classify(q2,plane2)); - tag3 = BOP_createTAG(BOP_classify(q2,plane3)); - BOP_TAG tagQ2 = BOP_createTAG(tag1,tag2,tag3); - if (tagQ2 == IN_IN_IN) return true; - - tag1 = BOP_createTAG(BOP_classify(q3,plane1)); - tag2 = BOP_createTAG(BOP_classify(q3,plane2)); - tag3 = BOP_createTAG(BOP_classify(q3,plane3)); - BOP_TAG tagQ3 = BOP_createTAG(tag1,tag2,tag3); - if (tagQ3 == IN_IN_IN) return true; - - if ((tagQ1 & OUT_OUT_OUT) == 0 && (tagQ2 & OUT_OUT_OUT) == 0 && - (tagQ3 & OUT_OUT_OUT) == 0) return true; - else return false; -} diff --git a/intern/boolop/intern/BOP_Face2Face.h b/intern/boolop/intern/BOP_Face2Face.h deleted file mode 100644 index 9809084ce3b..00000000000 --- a/intern/boolop/intern/BOP_Face2Face.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file boolop/intern/BOP_Face2Face.h - * \ingroup boolopintern - */ - - -#ifndef __BOP_FACE2FACE_H__ -#define __BOP_FACE2FACE_H__ - -#include "BOP_Mesh.h" -#include "BOP_Segment.h" -#include "BOP_Triangulator.h" -#include "BOP_Splitter.h" -#include "BOP_BSPTree.h" - -void BOP_Face2Face(BOP_Mesh *mesh, BOP_Faces *facesA, BOP_Faces *facesB); -void BOP_sew(BOP_Mesh *mesh, BOP_Faces *facesA, BOP_Faces *facesB); -void BOP_removeOverlappedFaces(BOP_Mesh *mesh, BOP_Faces *facesA, BOP_Faces *facesB); - -#endif diff --git a/intern/boolop/intern/BOP_Indexs.h b/intern/boolop/intern/BOP_Indexs.h deleted file mode 100644 index e001f412c9f..00000000000 --- a/intern/boolop/intern/BOP_Indexs.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file boolop/intern/BOP_Indexs.h - * \ingroup boolopintern - */ - - -#ifndef __BOP_INDEXS_H__ -#define __BOP_INDEXS_H__ - -#include <vector> - -typedef unsigned int BOP_Index; -typedef std::vector<BOP_Index> BOP_Indexs; -typedef std::vector<BOP_Index>::iterator BOP_IT_Indexs; - -#endif diff --git a/intern/boolop/intern/BOP_Interface.cpp b/intern/boolop/intern/BOP_Interface.cpp deleted file mode 100644 index b18a4334263..00000000000 --- a/intern/boolop/intern/BOP_Interface.cpp +++ /dev/null @@ -1,535 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file boolop/intern/BOP_Interface.cpp - * \ingroup boolopintern - */ - - -#include <iostream> -#include <map> -#include "../extern/BOP_Interface.h" -#include "../../bsp/intern/BSP_CSGMesh_CFIterator.h" -#include "BOP_BSPTree.h" -#include "BOP_Mesh.h" -#include "BOP_Face2Face.h" -#include "BOP_Merge.h" -#include "BOP_Merge2.h" -#include "BOP_Chrono.h" - -#if defined(BOP_ORIG_MERGE) && defined(BOP_NEW_MERGE) -#include "../../../source/blender/blenkernel/BKE_global.h" -#endif - -BoolOpState BOP_intersectionBoolOp(BOP_Mesh* meshC, - BOP_Faces* facesA, - BOP_Faces* facesB, - bool invertMeshA, - bool invertMeshB); -BOP_Face3* BOP_createFace(BOP_Mesh* mesh, - BOP_Index vertex1, - BOP_Index vertex2, - BOP_Index vertex3, - BOP_Index origFace); -void BOP_addMesh(BOP_Mesh* mesh, - BOP_Faces* meshFacesId, - CSG_FaceIteratorDescriptor& face_it, - CSG_VertexIteratorDescriptor& vertex_it, - bool invert); -BSP_CSGMesh* BOP_newEmptyMesh(); -BSP_CSGMesh* BOP_exportMesh(BOP_Mesh* inputMesh, - bool invert); -void BOP_meshFilter(BOP_Mesh* meshC, BOP_Faces* faces, BOP_BSPTree* bsp); -void BOP_simplifiedMeshFilter(BOP_Mesh* meshC, BOP_Faces* faces, BOP_BSPTree* bsp, bool inverted); -void BOP_meshClassify(BOP_Mesh* meshC, BOP_Faces* faces, BOP_BSPTree* bsp); - -/** - * Performs a generic booleam operation, the entry point for external modules. - * @param opType Boolean operation type BOP_INTERSECTION, BOP_UNION, BOP_DIFFERENCE - * @param outputMesh Output mesh, the final result (the object C) - * @param obAFaces Object A faces list - * @param obAVertices Object A vertices list - * @param obBFaces Object B faces list - * @param obBVertices Object B vertices list - * @param interpFunc Interpolating function - * @return operation state: BOP_OK, BOP_NO_SOLID, BOP_ERROR - */ -BoolOpState BOP_performBooleanOperation(BoolOpType opType, - BSP_CSGMesh** outputMesh, - CSG_FaceIteratorDescriptor obAFaces, - CSG_VertexIteratorDescriptor obAVertices, - CSG_FaceIteratorDescriptor obBFaces, - CSG_VertexIteratorDescriptor obBVertices) -{ - #ifdef BOP_DEBUG - std::cout << "BEGIN BOP_performBooleanOperation" << std::endl; - #endif - - // Set invert flags depending on boolean operation type: - // INTERSECTION: A^B = and(A,B) - // UNION: A|B = not(and(not(A),not(B))) - // DIFFERENCE: A-B = and(A,not(B)) - bool invertMeshA = (opType == BOP_UNION); - bool invertMeshB = (opType != BOP_INTERSECTION); - bool invertMeshC = (opType == BOP_UNION); - - // Faces list for both objects, used by boolean op. - BOP_Faces meshAFacesId; - BOP_Faces meshBFacesId; - - // Build C-mesh, the output mesh - BOP_Mesh meshC; - - // Add A-mesh into C-mesh - BOP_addMesh(&meshC, &meshAFacesId, obAFaces, obAVertices, invertMeshA); - - // Add B-mesh into C-mesh - BOP_addMesh(&meshC, &meshBFacesId, obBFaces, obBVertices, invertMeshB); - - // for now, allow operations on non-manifold (non-solid) meshes -#if 0 - if (!meshC.isClosedMesh()) - return BOP_NO_SOLID; -#endif - - // Perform the intersection boolean operation. - BoolOpState result = BOP_intersectionBoolOp(&meshC, &meshAFacesId, &meshBFacesId, - invertMeshA, invertMeshB); - - // Invert the output mesh if is required - *outputMesh = BOP_exportMesh(&meshC, invertMeshC); - - #ifdef BOP_DEBUG - std::cout << "END BOP_performBooleanOperation" << std::endl; - #endif - - return result; -} - -/** - * Computes the intersection boolean operation. Creates a new mesh resulting from - * an intersection of two meshes. - * @param meshC Input & Output mesh - * @param facesA Mesh A faces list - * @param facesB Mesh B faces list - * @param invertMeshA determines if object A is inverted - * @param invertMeshB determines if object B is inverted - * @return operation state: BOP_OK, BOP_NO_SOLID, BOP_ERROR - */ -BoolOpState BOP_intersectionBoolOp(BOP_Mesh* meshC, - BOP_Faces* facesA, - BOP_Faces* facesB, - bool invertMeshA, - bool invertMeshB) -{ - #ifdef BOP_DEBUG - BOP_Chrono chrono; - float t = 0.0f; - float c = 0.0f; - chrono.start(); - std::cout << "---" << std::endl; - #endif - - // Create BSPs trees for mesh A & B - BOP_BSPTree bspA; - bspA.addMesh(meshC, *facesA); - - BOP_BSPTree bspB; - bspB.addMesh(meshC, *facesB); - - #ifdef BOP_DEBUG - c = chrono.stamp(); t += c; - std::cout << "Create BSP " << c << std::endl; - #endif - - unsigned int numVertices = meshC->getNumVertexs(); - - // mesh pre-filter - BOP_simplifiedMeshFilter(meshC, facesA, &bspB, invertMeshB); - if ((0.25*facesA->size()) > bspB.getDeep()) - BOP_meshFilter(meshC, facesA, &bspB); - - BOP_simplifiedMeshFilter(meshC, facesB, &bspA, invertMeshA); - if ((0.25*facesB->size()) > bspA.getDeep()) - BOP_meshFilter(meshC, facesB, &bspA); - - #ifdef BOP_DEBUG - c = chrono.stamp(); t += c; - std::cout << "mesh Filter " << c << std::endl; - #endif - - // Face 2 Face - BOP_Face2Face(meshC,facesA,facesB); - - #ifdef BOP_DEBUG - c = chrono.stamp(); t += c; - std::cout << "Face2Face " << c << std::endl; - #endif - - // BSP classification - BOP_meshClassify(meshC,facesA,&bspB); - BOP_meshClassify(meshC,facesB,&bspA); - - #ifdef BOP_DEBUG - c = chrono.stamp(); t += c; - std::cout << "Classification " << c << std::endl; - #endif - - // Process overlapped faces - BOP_removeOverlappedFaces(meshC,facesA,facesB); - - #ifdef BOP_DEBUG - c = chrono.stamp(); t += c; - std::cout << "Remove overlap " << c << std::endl; - #endif - - // Sew two meshes - BOP_sew(meshC,facesA,facesB); - - #ifdef BOP_DEBUG - c = chrono.stamp(); t += c; - std::cout << "Sew " << c << std::endl; - #endif - - // Merge faces -#ifdef BOP_ORIG_MERGE -#ifndef BOP_NEW_MERGE - BOP_Merge::getInstance().mergeFaces(meshC,numVertices); -#endif -#endif - -#ifdef BOP_NEW_MERGE -#ifndef BOP_ORIG_MERGE - BOP_Merge2::getInstance().mergeFaces(meshC,numVertices); -#else - static int state = -1; - if (G.rt == 100) { - if( state != 1 ) { - std::cout << "Boolean code using old merge technique." << std::endl; - state = 1; - } - BOP_Merge::getInstance().mergeFaces(meshC,numVertices); - } else { - if( state != 0 ) { - std::cout << "Boolean code using new merge technique." << std::endl; - state = 0; - } - BOP_Merge2::getInstance().mergeFaces(meshC,numVertices); - } -#endif -#endif - - #ifdef BOP_DEBUG - c = chrono.stamp(); t += c; - std::cout << "Merge faces " << c << std::endl; - std::cout << "Total " << t << std::endl; - // Test integrity - meshC->testMesh(); - #endif - - return BOP_OK; -} - -/** - * Preprocess to filter no collisioned faces. - * @param meshC Input & Output mesh data - * @param faces Faces list to test - * @param bsp BSP tree used to filter - */ -void BOP_meshFilter(BOP_Mesh* meshC, BOP_Faces* faces, BOP_BSPTree* bsp) -{ - BOP_IT_Faces it; - BOP_TAG tag; - - it = faces->begin(); - while (it!=faces->end()) { - BOP_Face *face = *it; - MT_Point3 p1 = meshC->getVertex(face->getVertex(0))->getPoint(); - MT_Point3 p2 = meshC->getVertex(face->getVertex(1))->getPoint(); - MT_Point3 p3 = meshC->getVertex(face->getVertex(2))->getPoint(); - if ((tag = bsp->classifyFace(p1,p2,p3,face->getPlane()))==OUT||tag==OUTON) { - face->setTAG(BROKEN); - it = faces->erase(it); - } - else if (tag == IN) { - it = faces->erase(it); - }else{ - it++; - } - } -} - -/** - * Pre-process to filter no collisioned faces. - * @param meshC Input & Output mesh data - * @param faces Faces list to test - * @param bsp BSP tree used to filter - * @param inverted determines if the object is inverted - */ -void BOP_simplifiedMeshFilter(BOP_Mesh* meshC, BOP_Faces* faces, BOP_BSPTree* bsp, bool inverted) -{ - BOP_IT_Faces it; - - it = faces->begin(); - while (it!=faces->end()) { - BOP_Face *face = *it; - MT_Point3 p1 = meshC->getVertex(face->getVertex(0))->getPoint(); - MT_Point3 p2 = meshC->getVertex(face->getVertex(1))->getPoint(); - MT_Point3 p3 = meshC->getVertex(face->getVertex(2))->getPoint(); - if (bsp->filterFace(p1,p2,p3,face)==OUT) { - if (!inverted) face->setTAG(BROKEN); - it = faces->erase(it); - } - else { - it++; - } - } -} - -/** - * Process to classify the mesh faces using a bsp tree. - * @param meshC Input & Output mesh data - * @param faces Faces list to classify - * @param bsp BSP tree used to face classify - */ -void BOP_meshClassify(BOP_Mesh* meshC, BOP_Faces* faces, BOP_BSPTree* bsp) -{ - for(BOP_IT_Faces face=faces->begin();face!=faces->end();face++) { - if ((*face)->getTAG()!=BROKEN) { - MT_Point3 p1 = meshC->getVertex((*face)->getVertex(0))->getPoint(); - MT_Point3 p2 = meshC->getVertex((*face)->getVertex(1))->getPoint(); - MT_Point3 p3 = meshC->getVertex((*face)->getVertex(2))->getPoint(); - if (bsp->simplifiedClassifyFace(p1,p2,p3,(*face)->getPlane())!=IN) { - (*face)->setTAG(BROKEN); - } - } - } -} - -/** - * Returns a new mesh triangle. - * @param meshC Input & Output mesh data - * @param vertex1 first vertex of the new face - * @param vertex2 second vertex of the new face - * @param vertex3 third vertex of the new face - * @param origFace identifier of the new face - * @return new the new face - */ -BOP_Face3 *BOP_createFace3(BOP_Mesh* mesh, - BOP_Index vertex1, - BOP_Index vertex2, - BOP_Index vertex3, - BOP_Index origFace) -{ - MT_Point3 p1 = mesh->getVertex(vertex1)->getPoint(); - MT_Point3 p2 = mesh->getVertex(vertex2)->getPoint(); - MT_Point3 p3 = mesh->getVertex(vertex3)->getPoint(); - MT_Plane3 plane(p1,p2,p3); - - return new BOP_Face3(vertex1, vertex2, vertex3, plane, origFace); -} - -/** - * Adds mesh information into destination mesh. - * @param mesh input/output mesh, destination for the new mesh data - * @param meshFacesId output mesh faces, contains an added faces list - * @param face_it faces iterator - * @param vertex_it vertices iterator - * @param inverted if TRUE adding inverted faces, non-inverted otherwise - */ -void BOP_addMesh(BOP_Mesh* mesh, - BOP_Faces* meshFacesId, - CSG_FaceIteratorDescriptor& face_it, - CSG_VertexIteratorDescriptor& vertex_it, - bool invert) -{ - unsigned int vtxIndexOffset = mesh->getNumVertexs(); - - // The size of the vertex data array will be at least the number of faces. - CSG_IVertex vertex; - while (!vertex_it.Done(vertex_it.it)) { - vertex_it.Fill(vertex_it.it,&vertex); - MT_Point3 pos(vertex.position); - mesh->addVertex(pos); - vertex_it.Step(vertex_it.it); - } - - CSG_IFace face; - - // now for the polygons. - // we may need to decalare some memory for user defined face properties. - - BOP_Face3 *newface; - - while (!face_it.Done(face_it.it)) { - face_it.Fill(face_it.it,&face); - - // Let's not rely on quads being coplanar - especially if they - // are coming out of that soup of code from blender... - if (face.vertex_number == 4){ - // QUAD - if (invert) { - newface = BOP_createFace3(mesh, - face.vertex_index[2] + vtxIndexOffset, - face.vertex_index[0] + vtxIndexOffset, - face.vertex_index[3] + vtxIndexOffset, - face.orig_face); - meshFacesId->push_back(newface); - mesh->addFace(newface); - newface = BOP_createFace3(mesh, - face.vertex_index[2] + vtxIndexOffset, - face.vertex_index[1] + vtxIndexOffset, - face.vertex_index[0] + vtxIndexOffset, - face.orig_face); - meshFacesId->push_back(newface); - mesh->addFace(newface); - } - else { - newface = BOP_createFace3(mesh, - face.vertex_index[0] + vtxIndexOffset, - face.vertex_index[2] + vtxIndexOffset, - face.vertex_index[3] + vtxIndexOffset, - face.orig_face); - meshFacesId->push_back(newface); - mesh->addFace(newface); - newface = BOP_createFace3(mesh, - face.vertex_index[0] + vtxIndexOffset, - face.vertex_index[1] + vtxIndexOffset, - face.vertex_index[2] + vtxIndexOffset, - face.orig_face); - meshFacesId->push_back(newface); - mesh->addFace(newface); - } - } - else { - // TRIANGLES - if (invert) { - newface = BOP_createFace3(mesh, - face.vertex_index[2] + vtxIndexOffset, - face.vertex_index[1] + vtxIndexOffset, - face.vertex_index[0] + vtxIndexOffset, - face.orig_face); - meshFacesId->push_back(newface); - mesh->addFace(newface); - } - else { - newface = BOP_createFace3(mesh, - face.vertex_index[0] + vtxIndexOffset, - face.vertex_index[1] + vtxIndexOffset, - face.vertex_index[2] + vtxIndexOffset, - face.orig_face); - meshFacesId->push_back(newface); - mesh->addFace(newface); - } - } - - face_it.Step(face_it.it); - } -} - -/** - * Returns an empty mesh with the specified properties. - * @return a new empty mesh - */ -BSP_CSGMesh* BOP_newEmptyMesh() -{ - BSP_CSGMesh* mesh = BSP_CSGMesh::New(); - if (mesh == NULL) return mesh; - - std::vector<BSP_MVertex>* vertices = new std::vector<BSP_MVertex>; - - mesh->SetVertices(vertices); - - return mesh; -} - -/** - * Exports a BOP_Mesh to a BSP_CSGMesh. - * @param mesh Input mesh - * @param invert if TRUE export with inverted faces, no inverted otherwise - * @return the corresponding new BSP_CSGMesh - */ -BSP_CSGMesh* BOP_exportMesh(BOP_Mesh* mesh, - bool invert) -{ - BSP_CSGMesh* outputMesh = BOP_newEmptyMesh(); - - if (outputMesh == NULL) return NULL; - - // vtx index dictionary, to translate indeces from input to output. - std::map<int,unsigned int> dic; - std::map<int,unsigned int>::iterator itDic; - - unsigned int count = 0; - - // Add a new face for each face in the input list - BOP_Faces faces = mesh->getFaces(); - BOP_Vertexs vertexs = mesh->getVertexs(); - - for (BOP_IT_Faces face = faces.begin(); face != faces.end(); face++) { - if ((*face)->getTAG()!=BROKEN){ - // Add output face - outputMesh->FaceSet().push_back(BSP_MFace()); - BSP_MFace& outFace = outputMesh->FaceSet().back(); - - // Copy face - outFace.m_verts.clear(); - outFace.m_plane = (*face)->getPlane(); - outFace.m_orig_face = (*face)->getOriginalFace(); - - // invert face if is required - if (invert) (*face)->invert(); - - // Add the face vertex if not added yet - for (unsigned int pos=0;pos<(*face)->size();pos++) { - BSP_VertexInd outVtxId; - BOP_Index idVertex = (*face)->getVertex(pos); - itDic = dic.find(idVertex); - if (itDic == dic.end()) { - // The vertex isn't added yet - outVtxId = BSP_VertexInd(outputMesh->VertexSet().size()); - BSP_MVertex outVtx((mesh->getVertex(idVertex))->getPoint()); - outVtx.m_edges.clear(); - outputMesh->VertexSet().push_back(outVtx); - dic[idVertex] = outVtxId; - count++; - } - else { - // The vertex is added - outVtxId = BSP_VertexInd(itDic->second); - } - - outFace.m_verts.push_back(outVtxId); - } - } - } - - // Build the mesh edges using topological informtion - outputMesh->BuildEdges(); - - return outputMesh; -} diff --git a/intern/boolop/intern/BOP_MathUtils.cpp b/intern/boolop/intern/BOP_MathUtils.cpp deleted file mode 100644 index 020de2163a3..00000000000 --- a/intern/boolop/intern/BOP_MathUtils.cpp +++ /dev/null @@ -1,471 +0,0 @@ -/* - * - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): Marc Freixas, Ken Hughes - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file boolop/intern/BOP_MathUtils.cpp - * \ingroup boolopintern - */ - - -#include "BOP_MathUtils.h" -#include <iostream> - -/** - * Compares two scalars with EPSILON accuracy. - * @param A scalar - * @param B scalar - * @return 1 if A > B, -1 if A < B, 0 otherwise - */ -int BOP_comp(const MT_Scalar A, const MT_Scalar B) -{ -#ifndef VAR_EPSILON - if (A >= B + BOP_EPSILON) return 1; - else if (B >= A + BOP_EPSILON) return -1; - else return 0; -#else - int expA, expB; - float mant; - frexp(A, &expA); /* get exponents of each number */ - frexp(B, &expB); - - if(expA < expB) /* find the larger exponent */ - expA = expB; - mant = frexp((A-B), &expB); /* get exponent of the difference */ - /* mantissa will only be zero is (A-B) is really zero; otherwise, also - * also allow a "reasonably" small exponent or "reasonably large" - * difference in exponents to be considers "close to zero" */ - if( mant == 0 || expB < -30 || expA - expB > 31) return 0; - else if( mant > 0) return 1; - else return -1; -#endif -} - -/** - * Compares a scalar with EPSILON accuracy. - * @param A scalar - * @return 1 if A > 0, -1 if A < 0, 0 otherwise - */ -int BOP_comp0(const MT_Scalar A) -{ - if (A >= BOP_EPSILON) return 1; - else if (0 >= A + BOP_EPSILON) return -1; - else return 0; -} - -/** - * Compares two scalar triplets with EPSILON accuracy. - * @param A scalar triplet - * @param B scalar triplet - * @return 1 if A > B, -1 if A < B, 0 otherwise - */ -int BOP_comp(const MT_Tuple3& A, const MT_Tuple3& B) -{ -#ifndef VAR_EPSILON - if (A.x() >= (B.x() + BOP_EPSILON)) return 1; - else if (B.x() >= (A.x() + BOP_EPSILON)) return -1; - else if (A.y() >= (B.y() + BOP_EPSILON)) return 1; - else if (B.y() >= (A.y() + BOP_EPSILON)) return -1; - else if (A.z() >= (B.z() + BOP_EPSILON)) return 1; - else if (B.z() >= (A.z() + BOP_EPSILON)) return -1; - else return 0; -#else - int result = BOP_comp(A.x(), B.x()); - if (result != 0) return result; - result = BOP_comp(A.y(), B.y()); - if (result != 0) return result; - return BOP_comp(A.z(), B.z()); -#endif -} - -/** - * Compares two scalars strictly. - * @param A scalar - * @param B scalar - * @return 1 if A > B, -1 if A < B, 0 otherwise - */ -int BOP_exactComp(const MT_Scalar A, const MT_Scalar B) -{ - if (A > B) return 1; - else if (B > A) return -1; - else return 0; -} -/** - * Compares two scalar strictly. - * @param A scalar triplet - * @param B scalar triplet - * @return 1 if A > B, -1 if A < B, 0 otherwise - */ -int BOP_exactComp(const MT_Tuple3& A, const MT_Tuple3& B) -{ - if (A.x() > B.x()) return 1; - else if (B.x() > A.x()) return -1; - else if (A.y() > B.y()) return 1; - else if (B.y() > A.y()) return -1; - else if (A.z() > B.z()) return 1; - else if (B.z() > A.z()) return -1; - else return 0; -} - -/** - * Returns if p1 is between p2 and p3 and lay on the same line (are collinears). - * @param p1 point - * @param p2 point - * @param p3 point - * @return true if p1 is between p2 and p3 and lay on the same line, false otherwise - */ -bool BOP_between(const MT_Point3& p1, const MT_Point3& p2, const MT_Point3& p3) -{ - MT_Scalar distance = p2.distance(p3); - return (p1.distance(p2) < distance && p1.distance(p3) < distance) && BOP_collinear(p1,p2,p3); -} - -/** - * Returns if three points lay on the same line (are collinears). - * @param p1 point - * @param p2 point - * @param p3 point - * @return true if the three points lay on the same line, false otherwise - */ -bool BOP_collinear(const MT_Point3& p1, const MT_Point3& p2, const MT_Point3& p3) -{ - if( BOP_comp(p1,p2) == 0 || BOP_comp(p2,p3) == 0 ) return true; - - MT_Vector3 v1 = p2 - p1; - MT_Vector3 v2 = p3 - p2; - - /* normalize vectors before taking their cross product, so its length - * has some actual meaning */ - // if(MT_fuzzyZero(v1.length()) || MT_fuzzyZero(v2.length())) return true; - v1.normalize(); - v2.normalize(); - - MT_Vector3 w = v1.cross(v2); - - return (BOP_fuzzyZero(w.x()) && BOP_fuzzyZero(w.y()) && BOP_fuzzyZero(w.z())); -} - -/** - * Returns if a quad (coplanar) is convex. - * @return true if the quad is convex, false otherwise - */ -bool BOP_convex(const MT_Point3& p1, const MT_Point3& p2, const MT_Point3& p3, const MT_Point3& p4) -{ - MT_Vector3 v1 = p3 - p1; - MT_Vector3 v2 = p4 - p2; - MT_Vector3 quadPlane = v1.cross(v2); - // plane1 is the perpendicular plane that contains the quad diagonal (p2,p4) - MT_Plane3 plane1(quadPlane.cross(v2),p2); - // if p1 and p3 are classified in the same region, the quad is not convex - if (BOP_classify(p1,plane1) == BOP_classify(p3,plane1)) return false; - else { - // Test the other quad diagonal (p1,p3) and perpendicular plane - MT_Plane3 plane2(quadPlane.cross(v1),p1); - // if p2 and p4 are classified in the same region, the quad is not convex - return (BOP_classify(p2,plane2) != BOP_classify(p4,plane2)); - } -} - -/** - * Returns if a quad (coplanar) is concave and where is the split edge. - * @return 0 if is convex, 1 if is concave and split edge is p1-p3 and -1 if is - * cancave and split edge is p2-p4. - */ -int BOP_concave(const MT_Point3& p1, const MT_Point3& p2, const MT_Point3& p3, const MT_Point3& p4) -{ - MT_Vector3 v1 = p3 - p1; - MT_Vector3 v2 = p4 - p2; - MT_Vector3 quadPlane = v1.cross(v2); - // plane1 is the perpendicular plane that contains the quad diagonal (p2,p4) - MT_Plane3 plane1(quadPlane.cross(v2),p2); - // if p1 and p3 are classified in the same region, the quad is not convex - if (BOP_classify(p1,plane1) == BOP_classify(p3,plane1)) return 1; - else { - // Test the other quad diagonal (p1,p3) and perpendicular plane - MT_Plane3 plane2(quadPlane.cross(v1),p1); - // if p2 and p4 are classified in the same region, the quad is not convex - if (BOP_classify(p2,plane2) == BOP_classify(p4,plane2)) return -1; - else return 0; - } -} - -/** - * Computes the intersection between two lines (on the same plane). - * @param vL1 first line vector - * @param pL1 first line point - * @param vL2 second line vector - * @param pL2 second line point - * @param intersection intersection point (if exists) - * @return false if lines are parallels, true otherwise - */ -bool BOP_intersect(const MT_Vector3& vL1, const MT_Point3& pL1, const MT_Vector3& vL2, - const MT_Point3& pL2, MT_Point3 &intersection) -{ - // NOTE: - // If the lines aren't on the same plane, the intersection point will not be valid. - // So be careful !! - - MT_Scalar t = -1; - MT_Scalar den = (vL1.y()*vL2.x() - vL1.x() * vL2.y()); - - if (!BOP_fuzzyZero(den)) { - t = (pL2.y()*vL1.x() - vL1.y()*pL2.x() + pL1.x()*vL1.y() - pL1.y()*vL1.x()) / den; - } - else { - den = (vL1.y()*vL2.z() - vL1.z() * vL2.y()); - if (!BOP_fuzzyZero(den)) { - t = (pL2.y()*vL1.z() - vL1.y()*pL2.z() + pL1.z()*vL1.y() - pL1.y()*vL1.z()) / den; - } - else { - den = (vL1.x()*vL2.z() - vL1.z() * vL2.x()); - if (!BOP_fuzzyZero(den)) { - t = (pL2.x()*vL1.z() - vL1.x()*pL2.z() + pL1.z()*vL1.x() - pL1.x()*vL1.z()) / den; - } - else { - return false; - } - } - } - - intersection.setValue(vL2.x()*t + pL2.x(), vL2.y()*t + pL2.y(), vL2.z()*t + pL2.z()); - return true; -} - -/** - * Returns the center of the circle defined by three points. - * @param p1 point - * @param p2 point - * @param p3 point - * @param center circle center - * @return false if points are collinears, true otherwise - */ -bool BOP_getCircleCenter(const MT_Point3& p1, const MT_Point3& p2, const MT_Point3& p3, - MT_Point3& center) -{ - // Compute quad plane - MT_Vector3 p1p2 = p2-p1; - MT_Vector3 p1p3 = p3-p1; - MT_Plane3 plane1(p1,p2,p3); - MT_Vector3 plane = plane1.Normal(); - - // Compute first line vector, perpendicular to plane vector and edge (p1,p2) - MT_Vector3 vL1 = p1p2.cross(plane); - if( MT_fuzzyZero(vL1.length() ) ) - return false; - vL1.normalize(); - - // Compute first line point, middle point of edge (p1,p2) - MT_Point3 pL1 = p1.lerp(p2, 0.5); - - // Compute second line vector, perpendicular to plane vector and edge (p1,p3) - MT_Vector3 vL2 = p1p3.cross(plane); - if( MT_fuzzyZero(vL2.length() ) ) - return false; - vL2.normalize(); - - // Compute second line point, middle point of edge (p1,p3) - MT_Point3 pL2 = p1.lerp(p3, 0.5); - - // Compute intersection (the lines lay on the same plane, so the intersection exists - // only if they are not parallel!!) - return BOP_intersect(vL1,pL1,vL2,pL2,center); -} - -/** - * Returns if points q is inside the circle defined by p1, p2 and p3. - * @param p1 point - * @param p2 point - * @param p3 point - * @param q point - * @return true if p4 or p5 are inside the circle, false otherwise. If - * the circle does not exist (p1, p2 and p3 are collinears) returns true - */ -bool BOP_isInsideCircle(const MT_Point3& p1, const MT_Point3& p2, const MT_Point3& p3, - const MT_Point3& q) -{ - MT_Point3 center; - - // Compute circle center - bool ok = BOP_getCircleCenter(p1,p2,p3,center); - - if (!ok) return true; // p1,p2 and p3 are collinears - - // Check if q is inside the circle - MT_Scalar r = p1.distance(center); - MT_Scalar d = q.distance(center); - return (BOP_comp(d,r) <= 0); -} - -/** - * Returns if points p4 or p5 is inside the circle defined by p1, p2 and p3. - * @param p1 point - * @param p2 point - * @param p3 point - * @param p4 point - * @param p5 point - * @return true if p4 or p5 is inside the circle, false otherwise. If - * the circle does not exist (p1, p2 and p3 are collinears) returns true - */ -bool BOP_isInsideCircle(const MT_Point3& p1, const MT_Point3& p2, const MT_Point3& p3, - const MT_Point3& p4, const MT_Point3& p5) -{ - MT_Point3 center; - bool ok = BOP_getCircleCenter(p1,p2,p3,center); - - if (!ok) return true; // Collinear points! - - // Check if p4 or p5 is inside the circle - MT_Scalar r = p1.distance(center); - MT_Scalar d1 = p4.distance(center); - MT_Scalar d2 = p5.distance(center); - return (BOP_comp(d1,r) <= 0 || BOP_comp(d2,r) <= 0); -} - -/** - * Returns if two planes share the same orientation. - * @return >0 if planes share the same orientation - */ -MT_Scalar BOP_orientation(const MT_Plane3& p1, const MT_Plane3& p2) -{ - // Dot product between plane normals - return (p1.x()*p2.x() + p1.y()*p2.y() + p1.z()*p2.z()); -} - -/** - * Classifies a point according to the specified plane with EPSILON accuracy. - * @param p point - * @param plane plane - * @return >0 if the point is above (OUT), - * =0 if the point is on (ON), - * <0 if the point is below (IN) - */ -int BOP_classify(const MT_Point3& p, const MT_Plane3& plane) -{ - // Compare plane - point distance with zero - return BOP_comp0(plane.signedDistance(p)); -} - -/** - * Intersects a plane with the line that contains the specified points. - * @param plane split plane - * @param p1 first line point - * @param p2 second line point - * @return intersection between plane and line that contains p1 and p2 - */ -MT_Point3 BOP_intersectPlane(const MT_Plane3& plane, const MT_Point3& p1, const MT_Point3& p2) -{ - // Compute intersection between plane and line ... - // - // L: (p2-p1)lambda + p1 - // - // supposes resolve equation ... - // - // coefA*((p2.x - p1.y)*lambda + p1.x) + ... + coefD = 0 - - MT_Point3 intersection = MT_Point3(0,0,0); //never ever return anything undefined! - MT_Scalar den = plane.x()*(p2.x()-p1.x()) + - plane.y()*(p2.y()-p1.y()) + - plane.z()*(p2.z()-p1.z()); - if (den != 0) { - MT_Scalar lambda = (-plane.x()*p1.x()-plane.y()*p1.y()-plane.z()*p1.z()-plane.w()) / den; - intersection.setValue(p1.x() + (p2.x()-p1.x())*lambda, - p1.y() + (p2.y()-p1.y())*lambda, - p1.z() + (p2.z()-p1.z())*lambda); - return intersection; - } - return intersection; -} - -/** - * Returns if a plane contains a point with EPSILON accuracy. - * @param plane plane - * @param point point - * @return true if the point is on the plane, false otherwise - */ -bool BOP_containsPoint(const MT_Plane3& plane, const MT_Point3& point) -{ - return BOP_fuzzyZero(plane.signedDistance(point)); -} - -/** - * Pre: p0, p1 and p2 is a triangle and q is an interior point. - * @param p0 point - * @param p1 point - * @param p2 point - * @param q point - * @return intersection point I - * v - * (p0)-----(I)----->(p1) - * \ ^ / - * \ |w / - * \ | / - * \ (q) / - * \ | / - * \ | / - * \ | / - * (p2) - * - * v = P1-P2 - * w = P3-Q - * r0(t) = v*t+P1 - * r1(t) = w*t+P3 - * I = r0^r1 - */ -MT_Point3 BOP_4PointIntersect(const MT_Point3& p0, const MT_Point3& p1, const MT_Point3& p2, - const MT_Point3& q) -{ - MT_Vector3 v(p0.x()-p1.x(), p0.y()-p1.y(), p0.z()-p1.z()); - MT_Vector3 w(p2.x()-q.x(), p2.y()-q.y(), p2.z()-q.z()); - MT_Point3 I; - - BOP_intersect(v,p0,w,p2,I); - return I; -} - -/** - * Pre: p0, p1 and q are collinears. - * @param p0 point - * @param p1 point - * @param q point - * @return 0 if q == p0, 1 if q == p1, or a value between 0 and 1 otherwise - * - * (p0)-----(q)------------(p1) - * |<-d1-->| | - * |<---------d0---------->| - * - */ -MT_Scalar BOP_EpsilonDistance(const MT_Point3& p0, const MT_Point3& p1, const MT_Point3& q) -{ - MT_Scalar d0 = p0.distance(p1); - MT_Scalar d1 = p0.distance(q); - MT_Scalar d; - - if (BOP_fuzzyZero(d0)) d = 1.0; - else if (BOP_fuzzyZero(d1)) d = 0.0; - else d = d1 / d0; - return d; -} diff --git a/intern/boolop/intern/BOP_MathUtils.h b/intern/boolop/intern/BOP_MathUtils.h deleted file mode 100644 index 38acd98dd3d..00000000000 --- a/intern/boolop/intern/BOP_MathUtils.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): Marc Freixas, Ken Hughes - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file boolop/intern/BOP_MathUtils.h - * \ingroup boolopintern - */ - - -#ifndef __BOP_MATHUTILS_H__ -#define __BOP_MATHUTILS_H__ - -#include <math.h> -#include <float.h> -#include "MT_Point3.h" -#include "MT_Plane3.h" - -/* define this to give better precision comparisons */ -#define VAR_EPSILON - -#ifndef VAR_EPSILON -const MT_Scalar BOP_EPSILON(1.0e-5); -#else -const MT_Scalar BOP_EPSILON(9.3132257461547852e-10); /* ~= 2**-30 */ -#endif - -inline int BOP_sign(MT_Scalar x) { - return x < 0.0 ? -1 : x > 0.0 ? 1 : 0; -} -inline MT_Scalar BOP_abs(MT_Scalar x) { return fabs(x); } -int BOP_comp(const MT_Scalar A, const MT_Scalar B); -int BOP_comp(const MT_Tuple3& A, const MT_Tuple3& B); -int BOP_comp0(const MT_Scalar A); -inline bool BOP_fuzzyZero(MT_Scalar x) { return BOP_comp0(x) == 0; } -int BOP_exactComp(const MT_Scalar A, const MT_Scalar B); -int BOP_exactComp(const MT_Tuple3& A, const MT_Tuple3& B); -bool BOP_between(const MT_Point3& p1, const MT_Point3& p2, const MT_Point3& p3); -bool BOP_collinear(const MT_Point3& p1, const MT_Point3& p2, const MT_Point3& p3); -bool BOP_convex(const MT_Point3& p1, const MT_Point3& p2, const MT_Point3& p3, - const MT_Point3& p4); -int BOP_concave(const MT_Point3& p1, const MT_Point3& p2, const MT_Point3& p3, const MT_Point3& p4); -bool BOP_intersect(const MT_Vector3& vL1, const MT_Point3& pL1, const MT_Vector3& vL2, - const MT_Point3& pL2, MT_Point3& intersection); -bool BOP_getCircleCenter(const MT_Point3& p1, const MT_Point3& p2, const MT_Point3& p3, - const MT_Point3& center); -bool BOP_isInsideCircle(const MT_Point3& p1, const MT_Point3& p2, const MT_Point3& p3, - const MT_Point3& p4, const MT_Point3& p5); -bool BOP_isInsideCircle(const MT_Point3& p1, const MT_Point3& p2, const MT_Point3& p3, - const MT_Point3& q); -MT_Scalar BOP_orientation(const MT_Plane3& p1, const MT_Plane3& p2); -int BOP_classify(const MT_Point3& p, const MT_Plane3& plane); -MT_Point3 BOP_intersectPlane(const MT_Plane3& plane, const MT_Point3& p1, const MT_Point3& p2); -bool BOP_containsPoint(const MT_Plane3& plane, const MT_Point3& point); -MT_Point3 BOP_4PointIntersect(const MT_Point3& p0, const MT_Point3& p1, const MT_Point3& p2, - const MT_Point3& q); -MT_Scalar BOP_EpsilonDistance(const MT_Point3& p0, const MT_Point3& p1, const MT_Point3& q); - -#endif diff --git a/intern/boolop/intern/BOP_Merge.cpp b/intern/boolop/intern/BOP_Merge.cpp deleted file mode 100644 index 0baa6e7be67..00000000000 --- a/intern/boolop/intern/BOP_Merge.cpp +++ /dev/null @@ -1,811 +0,0 @@ -/* - * - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): Marc Freixas, Ken Hughes - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file boolop/intern/BOP_Merge.cpp - * \ingroup boolopintern - */ - - -#include "BOP_Merge.h" - -#ifdef BOP_ORIG_MERGE - -#ifdef _MSC_VER -#if _MSC_VER < 1300 -#include <list> -#endif -#endif - -/** - * SINGLETON (use method BOP_Merge.getInstance). - */ -BOP_Merge BOP_Merge::SINGLETON; - -/** - * Simplifies a mesh, merging its faces. - * @param m mesh - * @param v index of the first mergeable vertex (can be removed by merge) - */ -void BOP_Merge::mergeFaces(BOP_Mesh *m, BOP_Index v) -{ - m_mesh = m; - m_firstVertex = v; - - bool cont = false; - - // Merge faces - mergeFaces(); - - do { - // Add quads ... - cont = createQuads(); - if (cont) { - // ... and merge new faces - cont = mergeFaces(); - } - // ... until the merge is not succesful - } while(cont); -} - -/** - * Simplifies a mesh, merging its faces. - */ -bool BOP_Merge::mergeFaces() -{ - BOP_Indexs mergeVertices; - BOP_Vertexs vertices = m_mesh->getVertexs(); - BOP_IT_Vertexs v = vertices.begin(); - const BOP_IT_Vertexs verticesEnd = vertices.end(); - - // Advance to first mergeable vertex - advance(v,m_firstVertex); - BOP_Index pos = m_firstVertex; - - // Add unbroken vertices to the list - while(v!=verticesEnd) { - if ((*v)->getTAG() != BROKEN) mergeVertices.push_back(pos); - v++;pos++; - } - - // Merge faces with that vertices - return mergeFaces(mergeVertices); -} - - -/** - * Simplifies a mesh, merging the faces with the specified vertices. - * @param mergeVertices vertices to test - * @return true if a face merge was performed - */ -bool BOP_Merge::mergeFaces(BOP_Indexs &mergeVertices) -{ - // Check size > 0! - if (mergeVertices.size() == 0) return false; - - // New faces added by merge - BOP_Faces newFaces; - - // Old faces removed by merge - BOP_Faces oldFaces; - - // Get the first vertex index and add it to - // the current pending vertices to merge - BOP_Index v = mergeVertices[0]; - BOP_Indexs pendingVertices; - pendingVertices.push_back(v); - - // Get faces with index v that come from the same original face - BOP_LFaces facesByOriginalFace; - getFaces(facesByOriginalFace,v); - - bool merged = true; - - // Check it has any unbroken face - if (facesByOriginalFace.size()==0) { - // v has not any unbroken face (so it's a new BROKEN vertex) - (m_mesh->getVertex(v))->setTAG(BROKEN); - merged = false; - } - - // Merge vertex faces - const BOP_IT_LFaces facesEnd = facesByOriginalFace.end(); - - for(BOP_IT_LFaces facesByOriginalFaceX = facesByOriginalFace.begin(); - (facesByOriginalFaceX != facesEnd)&&merged; - facesByOriginalFaceX++) { - merged = mergeFaces((*facesByOriginalFaceX),oldFaces,newFaces,pendingVertices,v); - } - - // Check if the are some pendingVertices to merge - if (pendingVertices.size() > 1 && merged) { - // There are pending vertices that we need to merge in order to merge v ... - for(unsigned int i=1;i<pendingVertices.size() && merged;i++) - merged = mergeFaces(oldFaces,newFaces,pendingVertices,pendingVertices[i]); - } - - // If merge was succesful ... - if (merged) { - // Set old faces to BROKEN... - const BOP_IT_Faces oldFacesEnd = oldFaces.end(); - for(BOP_IT_Faces face=oldFaces.begin();face!=oldFacesEnd;face++) - (*face)->setTAG(BROKEN); - - // ... and add merged faces (that are the new merged faces without pending vertices) - const BOP_IT_Faces newFacesEnd = newFaces.end(); - for(BOP_IT_Faces newFace=newFaces.begin();newFace!=newFacesEnd;newFace++) { - m_mesh->addFace(*newFace); - // Also, add new face vertices to the queue of vertices to merge if they weren't - for(BOP_Index i = 0;i<(*newFace)->size();i++) { - BOP_Index vertexIndex = (*newFace)->getVertex(i); - if (vertexIndex >= m_firstVertex && !containsIndex(mergeVertices,vertexIndex)) - mergeVertices.push_back(vertexIndex); - } - } - // Set the merged vertices to BROKEN ... - const BOP_IT_Indexs pendingEnd = pendingVertices.end(); - for(BOP_IT_Indexs pendingVertex = pendingVertices.begin(); pendingVertex != pendingEnd;pendingVertex++) { - BOP_Index pV = *pendingVertex; - m_mesh->getVertex(pV)->setTAG(BROKEN); - // ... and remove them from mergeVertices queue - const BOP_IT_Indexs mergeEnd = mergeVertices.end(); - for(BOP_IT_Indexs mergeVertex = mergeVertices.begin(); mergeVertex != mergeEnd;mergeVertex++) { - BOP_Index mV = *mergeVertex; - if (mV == pV) { - mergeVertices.erase(mergeVertex); - break; - } - } - } - } - else { - // The merge was not succesful, remove the vertex frome merge vertices queue - mergeVertices.erase(mergeVertices.begin()); - - // free the not used newfaces - const BOP_IT_Faces newFacesEnd = newFaces.end(); - for(BOP_IT_Faces newFace=newFaces.begin();newFace!=newFacesEnd;newFace++) { - delete (*newFace); - } - } - - // Invoke mergeFaces and return the merge result - return (mergeFaces(mergeVertices) || merged); -} - - -/** - * Simplifies a mesh, merging the faces with vertex v that come from the same face. - * @param oldFaces sequence of old mesh faces obtained from the merge - * @param newFaces sequence of new mesh faces obtained from the merge - * @param vertices sequence of indexs (v1 ... vi = v ... vn) where : - * v is the current vertex to test, - * vj (j < i) are tested vertices, - * vk (k >= i) are vertices required to test to merge vj - * (so if a vertex vk can't be merged, the merge is not possible). - * @return true if the vertex v was 'merged' (obviously it could require to test - * some new vertices that will be added to the vertices list) - */ -bool BOP_Merge::mergeFaces(BOP_Faces &oldFaces, BOP_Faces &newFaces, BOP_Indexs &vertices, BOP_Index v) { - - bool merged = true; - - // Get faces with v that come from the same original face, (without the already 'merged' from vertices) - BOP_LFaces facesByOriginalFace; - getFaces(facesByOriginalFace,vertices,v); - - if (facesByOriginalFace.size()==0) { - // All the faces with this vertex were already merged!!! - return true; - } - else { - // Merge faces - const BOP_IT_LFaces facesEnd = facesByOriginalFace.end(); - for(BOP_IT_LFaces facesByOriginalFaceX = facesByOriginalFace.begin(); - (facesByOriginalFaceX != facesEnd)&&merged; - facesByOriginalFaceX++) { - merged = mergeFaces((*facesByOriginalFaceX),oldFaces,newFaces,vertices,v); - } - } - return merged; -} - - -/** - * Merge a set of faces removing the vertex index v. - * @param faces set of faces - * @param oldFaces set of old faces obtained from the merge - * @param newFaces set of new faces obtained from the merge - * @param vertices sequence of indexs (v1 ... vi = v ... vn) where : - * v is the current vertex to test, - * vj (j < i) are tested vertices, - * vk (k >= i) are vertices required to test to merge vj - * (so if a vertex vk can't be merged, the merge is not possible). - * @param v vertex index - * @return true if the merge is succesful, false otherwise - */ -bool BOP_Merge::mergeFaces(BOP_Faces &faces, BOP_Faces &oldFaces, BOP_Faces &newFaces, BOP_Indexs &vertices, BOP_Index v) -{ - - bool merged = false; - - if (faces.size() == 2) { - // Merge a pair of faces into a new face without v - BOP_Face *faceI = faces[0]; - BOP_Face *faceJ = faces[1]; - BOP_Face *faceK = mergeFaces(faceI,faceJ,vertices,v); - if (faceK != NULL) { - newFaces.push_back(faceK); - oldFaces.push_back(faceI); - oldFaces.push_back(faceJ); - merged = true; - } - else merged = false; - } - else if (faces.size() == 4) { - // Merge two pair of faces into a new pair without v - // First we try to perform a simplify merge to avoid more pending vertices - // (for example, if we have two triangles and two quads it will be better - // to do 3+4 and 3+4 than 3+3 and 4+4) - BOP_Face *oldFace1 = faces[0]; - BOP_Face *oldFace2, *newFace1; - unsigned int indexJ = 1; - while (indexJ < faces.size() && !merged) { - oldFace2 = faces[indexJ]; - newFace1 = mergeFaces(oldFace1,oldFace2,v); - if (newFace1 != NULL) merged = true; - else indexJ++; - } - if (merged) { - // Merge the other pair of faces - unsigned int indexK, indexL; - if (indexJ == 1) {indexK = 2;indexL = 3;} - else if (indexJ == 2) {indexK = 1;indexL = 3;} - else {indexK = 1;indexL = 2;} - BOP_Face *oldFace3 = faces[indexK]; - BOP_Face *oldFace4 = faces[indexL]; - unsigned int oldSize = vertices.size(); - BOP_Face *newFace2 = mergeFaces(oldFace3,oldFace4,vertices,v); - if (newFace2 != NULL) { - newFaces.push_back(newFace1); - newFaces.push_back(newFace2); - oldFaces.push_back(oldFace1); - oldFaces.push_back(oldFace2); - oldFaces.push_back(oldFace3); - oldFaces.push_back(oldFace4); - merged = true; - } - else { - // Undo all changes - delete newFace1; - merged = false; - unsigned int count = vertices.size() - oldSize; - if (count != 0) - vertices.erase(vertices.end() - count, vertices.end()); - } - } - if (!merged) { - // Try a complete merge - merged = true; - while (faces.size()>0 && merged) { - indexJ = 1; - BOP_Face *faceI = faces[0]; - merged = false; - while (indexJ < faces.size()) { - BOP_Face *faceJ = faces[indexJ]; - BOP_Face *faceK = mergeFaces(faceI,faceJ,vertices,v); - if (faceK != NULL) { - // faceK = faceI + faceJ and it does not include v! - faces.erase(faces.begin()+indexJ,faces.begin()+(indexJ+1)); - faces.erase(faces.begin(),faces.begin()+1); - newFaces.push_back(faceK); - oldFaces.push_back(faceI); - oldFaces.push_back(faceJ); - merged = true; - break; - } - else indexJ++; - } - } - } - } - else merged = false; // there are N=1 or N=3 or N>4 faces! - - // Return merge result - return merged; -} - -/** - * Returns a new quad from the merge of two faces (one quad and one triangle) - * that share the vertex v and come from the same original face. - * @param faceI mesh face (quad or triangle) with index v - * @param faceJ mesh face (quad or triangle) with index v - * @param v vertex index shared by both faces - * @return if the merge is possible, a new quad without v - */ -BOP_Face* BOP_Merge::mergeFaces(BOP_Face *faceI, BOP_Face *faceJ, BOP_Index v) -{ - if (faceI->size() == 3) { - if (faceJ->size() == 4) - return mergeFaces((BOP_Face4*)faceJ,(BOP_Face3*)faceI,v); - } - else if (faceI->size() == 4) { - if (faceJ->size() == 3) - return mergeFaces((BOP_Face4*)faceI,(BOP_Face3*)faceJ,v); - } - return NULL; -} - -/** - * Returns a new face from the merge of two faces (quads or triangles) that - * share te vertex v and come from the same original face. - * @param faceI mesh face (quad or triangle) with index v - * @param faceJ mesh face (quad or triangle) with index v - * @param pending vector with pending vertices (required to merge two quads into - * a new quad or one quad and one triangle into a new triangle; these merges - * suppose to remove two vertexs, v and its neighbour, that will be a pending - * vertex to merge if it wasn't) - * @param v vertex index shared by both faces - * @return if the merge is possible, a new face without v - */ -BOP_Face* BOP_Merge::mergeFaces(BOP_Face *faceI, BOP_Face *faceJ, BOP_Indexs &pending, BOP_Index v) -{ - if (faceI->size() == 3) { - if (faceJ->size() == 3) - return mergeFaces((BOP_Face3*)faceI,(BOP_Face3*)faceJ,v); - else if (faceJ->size() == 4) - return mergeFaces((BOP_Face4*)faceJ,(BOP_Face3*)faceI,pending,v); - } - else if (faceI->size() == 4) { - if (faceJ->size() == 3) - return mergeFaces((BOP_Face4*)faceI,(BOP_Face3*)faceJ,pending,v); - else if (faceJ->size() == 4) - return mergeFaces((BOP_Face4*)faceI,(BOP_Face4*)faceJ,pending,v); - } - return NULL; -} - -/** - * Returns a new triangle from the merge of two triangles that share the vertex - * v and come from the same original face. - * @param faceI mesh triangle - * @param faceJ mesh triangle - * @param v vertex index shared by both triangles - * @return If the merge is possible, a new triangle without v - */ -BOP_Face* BOP_Merge::mergeFaces(BOP_Face3 *faceI, BOP_Face3 *faceJ, BOP_Index v) -{ - BOP_Face *faceK = NULL; - - // Get faces data - BOP_Index prevI, nextI, prevJ, nextJ; - faceI->getNeighbours(v,prevI,nextI); - faceJ->getNeighbours(v,prevJ,nextJ); - MT_Point3 vertex = m_mesh->getVertex(v)->getPoint(); - MT_Point3 vPrevI = m_mesh->getVertex(prevI)->getPoint(); - MT_Point3 vNextI = m_mesh->getVertex(nextI)->getPoint(); - MT_Point3 vPrevJ = m_mesh->getVertex(prevJ)->getPoint(); - MT_Point3 vNextJ = m_mesh->getVertex(nextJ)->getPoint(); - - // Merge test - if (prevI == nextJ) { - // Both faces share the edge (prevI,v) == (v,nextJ) - if (BOP_between(vertex,vNextI,vPrevJ)) { - faceK = new BOP_Face3(prevI,prevJ,nextI,faceI->getPlane(),faceI->getOriginalFace()); - faceK->setTAG(faceI->getTAG()); - } - } - else if (nextI == prevJ) { - // Both faces share the edge (v,nextI) == (prevJ,v) - if (BOP_between(vertex,vPrevI,vNextJ)) { - faceK = new BOP_Face3(prevI,nextJ,nextI,faceI->getPlane(),faceI->getOriginalFace()); - faceK->setTAG(faceI->getTAG()); - } - } - return faceK; -} - -/** - * Returns a new quad from the merge of one quad and one triangle that share - * the vertex v and come from the same original face. - * @param faceI mesh quad - * @param faceJ mesh triangle - * @param v vertex index shared by both faces - * @return If the merge is possible, a new quad without v - */ -BOP_Face* BOP_Merge::mergeFaces(BOP_Face4 *faceI, BOP_Face3 *faceJ, BOP_Index v) -{ - BOP_Face *faceK = NULL; - - // Get faces data - BOP_Index prevI, nextI, opp, prevJ, nextJ; - faceI->getNeighbours(v,prevI,nextI,opp); - faceJ->getNeighbours(v,prevJ,nextJ); - MT_Point3 vertex = m_mesh->getVertex(v)->getPoint(); - MT_Point3 vOpp = m_mesh->getVertex(opp)->getPoint(); - MT_Point3 vPrevI = m_mesh->getVertex(prevI)->getPoint(); - MT_Point3 vNextI = m_mesh->getVertex(nextI)->getPoint(); - MT_Point3 vPrevJ = m_mesh->getVertex(prevJ)->getPoint(); - MT_Point3 vNextJ = m_mesh->getVertex(nextJ)->getPoint(); - - // Merge test - if (prevI == nextJ) { - if (BOP_between(vertex,vNextI,vPrevJ) && !BOP_collinear(vPrevJ,vPrevI,vOpp) - && BOP_convex(vOpp,vPrevI,vPrevJ,vNextI)) { - faceK = new BOP_Face4(opp,prevI,prevJ,nextI,faceI->getPlane(),faceI->getOriginalFace()); - faceK->setTAG(faceI->getTAG()); - } - } - else if (nextI == prevJ) { - if (BOP_between(vertex,vPrevI,vNextJ) && !BOP_collinear(vNextJ,vNextI,vOpp) - && BOP_convex(vOpp,vPrevI,vNextJ,vNextI)) { - faceK = new BOP_Face4(opp,prevI,nextJ,nextI,faceI->getPlane(),faceI->getOriginalFace()); - faceK->setTAG(faceI->getTAG()); - } - } - return faceK; -} - -/** - * Returns a new face (quad or triangle) from the merge of one quad and one - * triangle that share the vertex v and come from the same original face. - * @param faceI mesh quad - * @param faceJ mesh triangle - * @param pending vector with pending vertices (required to merge one quad - * and one triangle into a new triangle; it supposes to remove two vertexs, - * v and its neighbour, that will be a new pending vertex if it wasn't) - * @param v vertex index shared by both faces - * @return If the merge is possible, a new face without v - */ -BOP_Face* BOP_Merge::mergeFaces(BOP_Face4 *faceI, BOP_Face3 *faceJ, BOP_Indexs &pending, BOP_Index v) -{ - BOP_Face *faceK = NULL; - - // Get faces data - BOP_Index prevI, nextI, opp, prevJ, nextJ; - faceI->getNeighbours(v,prevI,nextI,opp); - faceJ->getNeighbours(v,prevJ,nextJ); - MT_Point3 vertex = m_mesh->getVertex(v)->getPoint(); - MT_Point3 vOpp = m_mesh->getVertex(opp)->getPoint(); - MT_Point3 vPrevI = m_mesh->getVertex(prevI)->getPoint(); - MT_Point3 vNextI = m_mesh->getVertex(nextI)->getPoint(); - MT_Point3 vPrevJ = m_mesh->getVertex(prevJ)->getPoint(); - MT_Point3 vNextJ = m_mesh->getVertex(nextJ)->getPoint(); - - // Merge test - if (prevI == nextJ) { - if (BOP_between(vertex,vNextI,vPrevJ)) { - if (!BOP_collinear(vPrevJ,vPrevI,vOpp) && BOP_convex(vOpp,vPrevI,vPrevJ,vNextI)) { - // The result is a new quad - faceK = new BOP_Face4(opp,prevI,prevJ,nextI,faceI->getPlane(),faceI->getOriginalFace()); - faceK->setTAG(faceI->getTAG()); - } - else if (BOP_between(vPrevI,vPrevJ,vOpp)) { - // The result is a triangle (only if prevI can be merged) - if (prevI < m_firstVertex) return NULL; // It can't be merged - faceK = new BOP_Face3(nextI,opp,prevJ,faceI->getPlane(),faceI->getOriginalFace()); - faceK->setTAG(faceI->getTAG()); - if (!containsIndex(pending, prevI)) pending.push_back(prevI); - } - } - } - else if (nextI == prevJ) { - if (BOP_between(vertex,vPrevI,vNextJ)) { - if (!BOP_collinear(vNextJ,vNextI,vOpp) && BOP_convex(vOpp,vPrevI,vNextJ,vNextI)) { - // The result is a new quad - faceK = new BOP_Face4(opp,prevI,nextJ,nextI,faceI->getPlane(),faceI->getOriginalFace()); - faceK->setTAG(faceI->getTAG()); - } - else if (BOP_between(vNextI,vOpp,vNextJ)) { - // The result is a triangle (only if nextI can be merged) - if (nextI < m_firstVertex) return NULL; - faceK = new BOP_Face3(prevI,nextJ,opp,faceI->getPlane(),faceI->getOriginalFace()); - faceK->setTAG(faceI->getTAG()); - if (!containsIndex(pending, nextI)) pending.push_back(nextI); - } - } - } - return faceK; -} - -/** - * Returns a new quad from the merge of two quads that share - * the vertex v and come from the same original face. - * @param faceI mesh quad - * @param faceJ mesh quad - * @param pending vector with pending vertices (required to merge the two - * quads supposes to remove two vertexs, v and its neighbour, - * that will be a new pending vertex if it wasn't) - * @param v vertex index shared by both quads - * @return If the merge is possible, a new quad without v - */ -BOP_Face* BOP_Merge::mergeFaces(BOP_Face4 *faceI, BOP_Face4 *faceJ, BOP_Indexs &pending, BOP_Index v) -{ - BOP_Face *faceK = NULL; - - // Get faces data - BOP_Index prevI, nextI, oppI, prevJ, nextJ, oppJ; - faceI->getNeighbours(v,prevI,nextI,oppI); - faceJ->getNeighbours(v,prevJ,nextJ,oppJ); - MT_Point3 vertex = m_mesh->getVertex(v)->getPoint(); - MT_Point3 vPrevI = m_mesh->getVertex(prevI)->getPoint(); - MT_Point3 vNextI = m_mesh->getVertex(nextI)->getPoint(); - MT_Point3 vOppI = m_mesh->getVertex(oppI)->getPoint(); - MT_Point3 vPrevJ = m_mesh->getVertex(prevJ)->getPoint(); - MT_Point3 vNextJ = m_mesh->getVertex(nextJ)->getPoint(); - MT_Point3 vOppJ = m_mesh->getVertex(oppJ)->getPoint(); - - // Merge test - if (prevI == nextJ) { - // prevI/nextJ will be a new vertex required to merge - if (prevI < m_firstVertex) return NULL; // It can't be merged - if (BOP_between(vertex,vPrevJ,vNextI) && BOP_between(vNextJ,vOppJ,vOppI)) { - faceK = new BOP_Face4(oppJ,prevJ,nextI,oppI,faceI->getPlane(),faceI->getOriginalFace()); - faceK->setTAG(faceI->getTAG()); - // We add prevI to the pending list if it wasn't yet - if (!containsIndex(pending, prevI)) pending.push_back(prevI); - } - } - else if (nextI == prevJ) { - // nextI/prevJ will be a new vertex required to merge - if (nextI < m_firstVertex) return NULL; // It can't be merged - if (BOP_between(vertex,vPrevI,vNextJ) && BOP_between(vNextI,vOppI,vOppJ)) { - faceK = new BOP_Face4(oppI,prevI,nextJ,oppJ,faceI->getPlane(),faceI->getOriginalFace()); - faceK->setTAG(faceI->getTAG()); - // Add nextI to the pending list if it wasn't yet - if (!containsIndex(pending, nextI)) pending.push_back(nextI); - } - } - return faceK; -} - - -/** - * Simplifies the mesh, merging the pairs of triangles that come frome the - * same original face and define a quad. - * @return true if a quad was added, false otherwise - */ -bool BOP_Merge::createQuads() -{ - - BOP_Faces quads; - - // Get mesh faces - BOP_Faces faces = m_mesh->getFaces(); - - - // Merge mesh triangles - const BOP_IT_Faces facesIEnd = (faces.end()-1); - const BOP_IT_Faces facesJEnd = faces.end(); - for(BOP_IT_Faces faceI=faces.begin();faceI!=facesIEnd;faceI++) { - if ((*faceI)->getTAG() == BROKEN || (*faceI)->size() != 3) continue; - for(BOP_IT_Faces faceJ=(faceI+1);faceJ!=facesJEnd;faceJ++) { - if ((*faceJ)->getTAG() == BROKEN || (*faceJ)->size() != 3 || - (*faceJ)->getOriginalFace() != (*faceI)->getOriginalFace()) continue; - - // Test if both triangles share a vertex index - BOP_Index v; - bool found = false; - for(unsigned int i=0;i<3 && !found;i++) { - v = (*faceI)->getVertex(i); - found = (*faceJ)->containsVertex(v); - - } - if (!found) continue; - - BOP_Face *faceK = createQuad((BOP_Face3*)*faceI,(BOP_Face3*)*faceJ,v); - if (faceK != NULL) { - // Set triangles to BROKEN - (*faceI)->setTAG(BROKEN); - (*faceJ)->setTAG(BROKEN); - quads.push_back(faceK); - break; - } - } - } - - // Add quads to mesh - const BOP_IT_Faces quadsEnd = quads.end(); - for(BOP_IT_Faces quad=quads.begin();quad!=quadsEnd;quad++) m_mesh->addFace(*quad); - return (quads.size() > 0); -} - -/** - * Returns a new quad (convex) from the merge of two triangles that share the - * vertex index v. - * @param faceI mesh triangle - * @param faceJ mesh triangle - * @param v vertex index shared by both triangles - * @return a new convex quad if the merge is possible - */ -BOP_Face* BOP_Merge::createQuad(BOP_Face3 *faceI, BOP_Face3 *faceJ, BOP_Index v) -{ - BOP_Face *faceK = NULL; - - // Get faces data - BOP_Index prevI, nextI, prevJ, nextJ; - faceI->getNeighbours(v,prevI,nextI); - faceJ->getNeighbours(v,prevJ,nextJ); - MT_Point3 vertex = m_mesh->getVertex(v)->getPoint(); - MT_Point3 vPrevI = m_mesh->getVertex(prevI)->getPoint(); - MT_Point3 vNextI = m_mesh->getVertex(nextI)->getPoint(); - MT_Point3 vPrevJ = m_mesh->getVertex(prevJ)->getPoint(); - MT_Point3 vNextJ = m_mesh->getVertex(nextJ)->getPoint(); - - // Quad test - if (prevI == nextJ) { - if (!BOP_collinear(vNextI,vertex,vPrevJ) && !BOP_collinear(vNextI,vPrevI,vPrevJ) && - BOP_convex(vertex,vNextI,vPrevI,vPrevJ)) { - faceK = new BOP_Face4(v,nextI,prevI,prevJ,faceI->getPlane(),faceI->getOriginalFace()); - faceK->setTAG(faceI->getTAG()); - } - } - else if (nextI == prevJ) { - if (!BOP_collinear(vPrevI,vertex,vNextJ) && !BOP_collinear(vPrevI,vNextI,vNextJ) && - BOP_convex(vertex,vNextJ,vNextI,vPrevI)) { - faceK = new BOP_Face4(v,nextJ,nextI,prevI,faceI->getPlane(),faceI->getOriginalFace()); - faceK->setTAG(faceI->getTAG()); - } - } - return faceK; -} - -/** - * Returns if a index is inside a set of indexs. - * @param indexs set of indexs - * @param i index - * @return true if the index is inside the set, false otherwise - */ -bool BOP_Merge::containsIndex(BOP_Indexs indexs, BOP_Index i) -{ - const BOP_IT_Indexs indexsEnd = indexs.end(); - for(BOP_IT_Indexs it=indexs.begin();it!=indexsEnd;it++) { - if (*it == i) return true; - } - return false; -} - -/** - * Creates a list of lists L1, L2, ... LN where - * LX = mesh faces with vertex v that come from the same original face - * @param facesByOriginalFace list of faces lists - * @param v vertex index - */ -void BOP_Merge::getFaces(BOP_LFaces &facesByOriginalFace, BOP_Index v) -{ - // Get edges with vertex v - BOP_Indexs edgeIndexs = m_mesh->getVertex(v)->getEdges(); - const BOP_IT_Indexs edgeEnd = edgeIndexs.end(); - for(BOP_IT_Indexs edgeIndex = edgeIndexs.begin();edgeIndex != edgeEnd;edgeIndex++) { - // Foreach edge, add its no broken faces to the output list - BOP_Edge* edge = m_mesh->getEdge(*edgeIndex); - BOP_Indexs faceIndexs = edge->getFaces(); - const BOP_IT_Indexs faceEnd = faceIndexs.end(); - for(BOP_IT_Indexs faceIndex=faceIndexs.begin();faceIndex!=faceEnd;faceIndex++) { - BOP_Face* face = m_mesh->getFace(*faceIndex); - if (face->getTAG() != BROKEN) { - bool found = false; - // Search if we already have created a list for the - // faces that come from the same original face - const BOP_IT_LFaces lfEnd = facesByOriginalFace.end(); - for(BOP_IT_LFaces facesByOriginalFaceX=facesByOriginalFace.begin(); - facesByOriginalFaceX!=lfEnd; facesByOriginalFaceX++) { - if (((*facesByOriginalFaceX)[0])->getOriginalFace() == face->getOriginalFace()) { - // Search that the face has not been added to the list before - for(unsigned int i = 0;i<(*facesByOriginalFaceX).size();i++) { - if ((*facesByOriginalFaceX)[i] == face) { - found = true; - break; - } - } - if (!found) { - // Add the face to the list - if (face->getTAG()==OVERLAPPED) facesByOriginalFaceX->insert(facesByOriginalFaceX->begin(),face); - else facesByOriginalFaceX->push_back(face); - found = true; - } - break; - } - } - if (!found) { - // Create a new list and add the current face - BOP_Faces facesByOriginalFaceX; - facesByOriginalFaceX.push_back(face); - facesByOriginalFace.push_back(facesByOriginalFaceX); - } - } - } - } -} - -/** - * Creates a list of lists L1, L2, ... LN where - * LX = mesh faces with vertex v that come from the same original face - * and without any of the vertices that appear before v in vertices - * @param facesByOriginalFace list of faces lists - * @param vertices vector with vertices indexs that contains v - * @param v vertex index - */ -void BOP_Merge::getFaces(BOP_LFaces &facesByOriginalFace, BOP_Indexs vertices, BOP_Index v) -{ - // Get edges with vertex v - BOP_Indexs edgeIndexs = m_mesh->getVertex(v)->getEdges(); - const BOP_IT_Indexs edgeEnd = edgeIndexs.end(); - for(BOP_IT_Indexs edgeIndex = edgeIndexs.begin();edgeIndex != edgeEnd;edgeIndex++) { - // Foreach edge, add its no broken faces to the output list - BOP_Edge* edge = m_mesh->getEdge(*edgeIndex); - BOP_Indexs faceIndexs = edge->getFaces(); - const BOP_IT_Indexs faceEnd = faceIndexs.end(); - for(BOP_IT_Indexs faceIndex=faceIndexs.begin();faceIndex!=faceEnd;faceIndex++) { - BOP_Face* face = m_mesh->getFace(*faceIndex); - if (face->getTAG() != BROKEN) { - // Search if the face contains any of the forbidden vertices - bool found = false; - for(BOP_IT_Indexs vertex = vertices.begin();*vertex!= v;vertex++) { - if (face->containsVertex(*vertex)) { - // face contains a forbidden vertex! - found = true; - break; - } - } - if (!found) { - // Search if we already have created a list with the - // faces that come from the same original face - const BOP_IT_LFaces lfEnd = facesByOriginalFace.end(); - for(BOP_IT_LFaces facesByOriginalFaceX=facesByOriginalFace.begin(); - facesByOriginalFaceX!=lfEnd; facesByOriginalFaceX++) { - if (((*facesByOriginalFaceX)[0])->getOriginalFace() == face->getOriginalFace()) { - // Search that the face has not been added to the list before - for(unsigned int i = 0;i<(*facesByOriginalFaceX).size();i++) { - if ((*facesByOriginalFaceX)[i] == face) { - found = true; - break; - } - } - if (!found) { - // Add face to the list - if (face->getTAG()==OVERLAPPED) facesByOriginalFaceX->insert(facesByOriginalFaceX->begin(),face); - else facesByOriginalFaceX->push_back(face); - found = true; - } - break; - } - } - if (!found) { - // Create a new list and add the current face - BOP_Faces facesByOriginalFaceX; - facesByOriginalFaceX.push_back(face); - facesByOriginalFace.push_back(facesByOriginalFaceX); - } - } - } - } - } -} - -#endif /* BOP_ORIG_MERGE */ diff --git a/intern/boolop/intern/BOP_Merge.h b/intern/boolop/intern/BOP_Merge.h deleted file mode 100644 index 9d6d7030ba7..00000000000 --- a/intern/boolop/intern/BOP_Merge.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file boolop/intern/BOP_Merge.h - * \ingroup boolopintern - */ - - -#ifndef __BOP_MERGE_H__ -#define __BOP_MERGE_H__ - -#include "BOP_Misc.h" - -#ifdef BOP_ORIG_MERGE -#include "BOP_Mesh.h" -#include "BOP_Tag.h" -#include "BOP_MathUtils.h" -#include "MEM_SmartPtr.h" - -typedef std::vector< BOP_Faces > BOP_LFaces; -typedef std::vector< BOP_Faces >::iterator BOP_IT_LFaces; - -class BOP_Merge { - private: - BOP_Mesh* m_mesh; - BOP_Index m_firstVertex; - static BOP_Merge SINGLETON; - - BOP_Merge() {}; - bool mergeFaces(); - bool mergeFaces(BOP_Indexs &mergeVertices); - bool mergeFaces(BOP_Faces &oldFaces, BOP_Faces &newFaces, BOP_Indexs &vertices, BOP_Index v); - bool mergeFaces(BOP_Faces &faces, BOP_Faces &oldFaces, BOP_Faces &newFaces, BOP_Indexs &vertices, BOP_Index v); - BOP_Face *mergeFaces(BOP_Face *faceI, BOP_Face *faceJ, BOP_Index v); - BOP_Face *mergeFaces(BOP_Face *faceI, BOP_Face *faceJ, BOP_Indexs &pending, BOP_Index v); - BOP_Face *mergeFaces(BOP_Face3 *faceI, BOP_Face3 *faceJ, BOP_Index v); - BOP_Face *mergeFaces(BOP_Face4 *faceI, BOP_Face3 *faceJ, BOP_Index v); - BOP_Face *mergeFaces(BOP_Face4 *faceI, BOP_Face3 *faceJ, BOP_Indexs &pending, BOP_Index v); - BOP_Face *mergeFaces(BOP_Face4 *faceI, BOP_Face4 *faceJ, BOP_Indexs &pending, BOP_Index v); - bool createQuads(); - BOP_Face *createQuad(BOP_Face3 *faceI, BOP_Face3 *faceJ, BOP_Index v); - bool containsIndex(BOP_Indexs indexs, BOP_Index index); - void getFaces(BOP_LFaces &facesByOriginalFace, BOP_Index v); - void getFaces(BOP_LFaces &facesByOriginalFace, BOP_Indexs vertices, BOP_Index v); - - public: - - static BOP_Merge &getInstance() { - return SINGLETON; - } - - void mergeFaces(BOP_Mesh *m, BOP_Index v); -}; - -#endif /* BOP_ORIG_MERGE */ - -#endif diff --git a/intern/boolop/intern/BOP_Merge2.cpp b/intern/boolop/intern/BOP_Merge2.cpp deleted file mode 100644 index 6bec9ba8222..00000000000 --- a/intern/boolop/intern/BOP_Merge2.cpp +++ /dev/null @@ -1,948 +0,0 @@ -/* - * - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): Marc Freixas, Ken Hughes - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file boolop/intern/BOP_Merge2.cpp - * \ingroup boolopintern - */ - - -#include "BOP_Merge2.h" - -#ifdef BOP_NEW_MERGE - -static void deleteFace(BOP_Mesh *m, BOP_Face *face); - -/** - * SINGLETON (use method BOP_Merge2.getInstance). - */ -BOP_Merge2 BOP_Merge2::SINGLETON; - -#ifdef BOP_DEBUG -void dumpmesh ( BOP_Mesh *m, bool force ) -{ - unsigned int nonmanifold = 0; - { - BOP_Edges edges = m->getEdges(); - int count = 0; - for (BOP_IT_Edges edge = edges.begin(); edge != edges.end(); - ++count, ++edge) { - if (!(*edge)->getUsed() && (*edge)->getFaces().size() == 0 ) continue; - BOP_Vertex * v1 = m->getVertex((*edge)->getVertex1()); - BOP_Vertex * v2 = m->getVertex((*edge)->getVertex2()); - - if(v1->getTAG()!= BROKEN || v2->getTAG()!= BROKEN ) { - int fcount = 0; - BOP_Indexs faces = (*edge)->getFaces(); - for (BOP_IT_Indexs face = faces.begin(); face != faces.end(); face++) { - BOP_Face *f = m->getFace(*face); - if(f->getTAG()== UNCLASSIFIED) ++fcount; - } - - - if(fcount !=0 && fcount !=2 ) { - ++nonmanifold; - } - } - } - if (!force && nonmanifold == 0) return; - } - if( nonmanifold ) - cout << nonmanifold << " edges detected" << endl; -#ifdef BOP_DEBUG - cout << "---------------------------" << endl; - - BOP_Edges edges = m->getEdges(); - int count = 0; - for (BOP_IT_Edges edge = edges.begin(); edge != edges.end(); - ++count, ++edge) { - BOP_Vertex * v1 = m->getVertex((*edge)->getVertex1()); - BOP_Vertex * v2 = m->getVertex((*edge)->getVertex2()); - - if(v1->getTAG()!= BROKEN || v2->getTAG()!= BROKEN ) { - int fcount = 0; - BOP_Indexs faces = (*edge)->getFaces(); - cout << count << ", " << (*edge) << ", " << faces.size() << endl; - for (BOP_IT_Indexs face = faces.begin(); face != faces.end(); face++) { - BOP_Face *f = m->getFace(*face); - if(f->getTAG()== UNCLASSIFIED) ++fcount; - cout << " face " << f << endl; - } - - - if(fcount !=0 && fcount !=2 ) - cout << " NON-MANIFOLD" << endl; - } - } - - BOP_Faces faces = m->getFaces(); - count = 0; - for (BOP_IT_Faces face = faces.begin(); face != faces.end(); face++) { - if( count < 12*2 || (*face)->getTAG() != BROKEN ) { - cout << count << ", " << *face << endl; - } - ++count; - } - - BOP_Vertexs verts = m->getVertexs(); - count = 0; - for (BOP_IT_Vertexs vert = verts.begin(); vert != verts.end(); vert++) { - cout << count++ << ", " << *vert << " " << (*vert)->getNumEdges() << endl; - BOP_Indexs edges = (*vert)->getEdges(); - for( BOP_IT_Indexs it = edges.begin(); it != edges.end(); ++it) { - BOP_Edge *edge = m->getEdge(*it); - cout << " " << edge << endl; - } - } - cout << "===========================" << endl; -#endif -} -#endif - -/** - * Simplifies a mesh, merging its faces. - * @param m mesh - * @param v index of the first mergeable vertex (can be removed by merge) - */ - -void BOP_Merge2::mergeFaces(BOP_Mesh *m, BOP_Index v) -{ - m_mesh = m; - -#ifdef BOP_DEBUG - cout << "##############################" << endl; -#endif - cleanup( ); - - m_firstVertex = v; - bool cont = false; - - // Merge faces - mergeFaces(); - - do { - // Add quads ... - cont = createQuads(); - // ... and merge new faces - if( cont ) cont = mergeFaces(); - -#ifdef BOP_DEBUG - cout << "called mergeFaces " << cont << endl; -#endif - // ... until the merge is not succesful - } while(cont); -} - -void clean_nonmanifold( BOP_Mesh *m ) -{ - return; - - BOP_Edges nme; - BOP_Edges e = m->getEdges(); - for( BOP_IT_Edges it = e.begin(); it != e.end(); ++it ) { - BOP_Indexs faces = (*it)->getFaces(); - if( faces.size() & ~2 ) - nme.push_back(*it); - } - if (nme.size() == 0) return; - for( BOP_IT_Edges it = nme.begin(); it != nme.end(); ++it ) { - if( (*it)->getFaces().size() > 1 ) { - BOP_Indexs faces = (*it)->getFaces(); - for( BOP_IT_Indexs face = faces.begin(); face != faces.end(); ++face ) { - MT_Point3 vertex1 = m->getVertex(m->getFace(*face)->getVertex(0))->getPoint(); - MT_Point3 vertex2 = m->getVertex(m->getFace(*face)->getVertex(1))->getPoint(); - MT_Point3 vertex3 = m->getVertex(m->getFace(*face)->getVertex(2))->getPoint(); - if (BOP_collinear(vertex1,vertex2,vertex3)) // collinear triangle - deleteFace(m,m->getFace(*face)); - } - continue; - } - BOP_Face *oface1 = m->getFace((*it)->getFaces().front()); - BOP_Face *oface2, *tmpface; - BOP_Index first =(*it)->getVertex1(); - BOP_Index next =(*it)->getVertex2(); - BOP_Index last = first; - unsigned short facecount = 0; - bool found = false; - BOP_Indexs vertList; -#ifdef BOP_DEBUG - cout << " first edge is " << (*it) << endl; -#endif - vertList.push_back(first); - BOP_Edge *edge; - while(true) { - BOP_Vertex *vert = m->getVertex(next); - BOP_Indexs edges = vert->getEdges(); - edge = NULL; - for( BOP_IT_Indexs eit = edges.begin(); eit != edges.end(); ++eit) { - edge = m->getEdge(*eit); - if( edge->getFaces().size() > 1) { - edge = NULL; - continue; - } - if( edge->getVertex1() == next && edge->getVertex2() != last ) { - last = next; - next = edge->getVertex2(); - break; - } - if( edge->getVertex2() == next && edge->getVertex1() != last ) { - last = next; - next = edge->getVertex1(); - break; - } - edge = NULL; - } - if( !edge ) break; -#ifdef BOP_DEBUG - cout << " next edge is " << edge << endl; -#endif - tmpface = m->getFace(edge->getFaces().front()); - if( oface1->getOriginalFace() != tmpface->getOriginalFace() ) - oface2 = tmpface; - else - ++facecount; - vertList.push_back(last); - if( vertList.size() > 3 ) break; - if( next == first ) { - found = true; - break; - } - } - if(found) { - edge = *it; -#ifdef BOP_DEBUG - cout << " --> found a loop" << endl; -#endif - if( vertList.size() == 3 ) { - BOP_Face3 *face = (BOP_Face3 *)m->getFace(edge->getFaces().front()); - face->getNeighbours(first,last,next); - } else if( vertList.size() == 4 ) { - BOP_Face4 *face = (BOP_Face4 *)m->getFace(edge->getFaces().front()); - face->getNeighbours(first,last,next,last); - } else { -#ifdef BOP_DEBUG - cout << "loop has " << vertList.size() << "verts"; -#endif - continue; - } - if(facecount == 1) oface1 = oface2; - next = vertList[1]; - last = vertList[2]; - if( edge->getVertex2() == next ) { - BOP_Face3 *f = new BOP_Face3(next,first,last, - oface1->getPlane(),oface1->getOriginalFace()); - m->addFace( f ); -#ifdef BOP_DEBUG - cout << " face is backward: " << f << endl; -#endif - - } else { - BOP_Face3 *f = new BOP_Face3(last,first,next, - oface1->getPlane(),oface1->getOriginalFace()); - m->addFace( f ); -#ifdef BOP_DEBUG - cout << " face is forward: " << f << endl; -#endif - } - } - } -} - -/** - * Runs through mesh and makes sure vert/face/edge data is consistent. Most - * importantly: - * (1) mark edges which are no longer used - * (2) remove broken faces from edges - * (3) remove faces from mesh which have a single edge belonging to no other - * face (non-manifold edges) - */ - -void BOP_Merge2::cleanup( void ) -{ - BOP_Edges edges = m_mesh->getEdges(); - for (BOP_IT_Edges edge = edges.begin(); edge != edges.end(); ++edge) { - BOP_Indexs faces = (*edge)->getFaces(); - for (BOP_IT_Indexs face = faces.begin(); face != faces.end(); ++face) { - BOP_Face *f = m_mesh->getFace(*face); - if (f->getTAG()== UNCLASSIFIED); - else (*edge)->removeFace(*face); - } - if( (*edge)->getFaces().size() == 0) (*edge)->setUsed(false); - } - - BOP_Vertexs v = m_mesh->getVertexs(); - for( BOP_IT_Vertexs it = v.begin(); it != v.end(); ++it ) { - if( (*it)->getTAG() != BROKEN) { - BOP_Indexs iedges = (*it)->getEdges(); - for(BOP_IT_Indexs i = iedges.begin();i!=iedges.end();i++) - if( m_mesh->getEdge((*i))->getUsed( ) == false) (*it)->removeEdge( *i ); - if( (*it)->getEdges().size() == 0 ) (*it)->setTAG(BROKEN); - } - } - // clean_nonmanifold( m_mesh ); -} - -/** - * Simplifies a mesh, merging its faces. - */ -bool BOP_Merge2::mergeFaces() -{ - BOP_Indexs mergeVertices; - BOP_Vertexs vertices = m_mesh->getVertexs(); - BOP_IT_Vertexs v = vertices.begin(); - const BOP_IT_Vertexs verticesEnd = vertices.end(); - - // Advance to first mergeable vertex - advance(v,m_firstVertex); - BOP_Index pos = m_firstVertex; - - // Add unbroken vertices to the list - while(v!=verticesEnd) { - if ((*v)->getTAG() != BROKEN) { - mergeVertices.push_back(pos); - } - - v++; - pos++; - } - - // Merge faces with that vertices - return mergeFaces(mergeVertices); -} - -/** - * remove edges from vertices when the vertex is removed - */ -void BOP_Merge2::freeVerts(BOP_Index v, BOP_Vertex *vert) -{ - BOP_Indexs edges = vert->getEdges(); - BOP_Vertex *other; - - for( BOP_IT_Indexs it = edges.begin(); it != edges.end(); ++it) { - BOP_Edge *edge = m_mesh->getEdge(*it); - BOP_Indexs edges2; - if( edge->getVertex1() != v ) - other = m_mesh->getVertex( edge->getVertex1() ); - else - other = m_mesh->getVertex( edge->getVertex2() ); - other->removeEdge(*it); - vert->removeEdge(*it); - } -} - -/** - * Simplifies a mesh, merging the faces with the specified vertices. - * @param mergeVertices vertices to test - * @return true if a face merge was performed - */ -bool BOP_Merge2::mergeFaces(BOP_Indexs &mergeVertices) -{ - // Check size > 0! - if (mergeVertices.size() == 0) return false; - bool didMerge = false; - - for( BOP_Index i = 0; i < mergeVertices.size(); ++i ) { - BOP_LFaces facesByOriginalFace; - BOP_Index v = mergeVertices[i]; - BOP_Vertex *vert = m_mesh->getVertex(v); -#ifdef BOP_DEBUG - cout << "i = " << i << ", v = " << v << ", vert = " << vert << endl; - if (v==48) - cout << "found vert 48" << endl; -#endif - if ( vert->getTAG() != BROKEN ) { - getFaces(facesByOriginalFace,v); - - switch (facesByOriginalFace.size()) { - case 0: - // v has no unbroken faces (so it's a new BROKEN vertex) - freeVerts( v, vert ); - vert->setTAG(BROKEN); - break; - case 2: { -#ifdef BOP_DEBUG - cout << "size of fBOF = " << facesByOriginalFace.size() << endl; -#endif - BOP_Faces ff = facesByOriginalFace.front(); - BOP_Faces fb = facesByOriginalFace.back(); - BOP_Index eindexs[2]; - int ecount = 0; - - // look for two edges adjacent to v which contain both ofaces - BOP_Indexs edges = vert->getEdges(); -#ifdef BOP_DEBUG - cout << " ff has " << ff.size() << " faces" << endl; - cout << " fb has " << fb.size() << " faces" << endl; - cout << " v has " << edges.size() << " edges" << endl; -#endif - for(BOP_IT_Indexs it = edges.begin(); it != edges.end(); - ++it ) { - BOP_Edge *edge = m_mesh->getEdge(*it); - BOP_Indexs faces = edge->getFaces(); -#ifdef BOP_DEBUG - cout << " " << edge << " has " << edge->getFaces().size() << " faces" << endl; -#endif - if( faces.size() == 2 ) { - BOP_Face *f0 = m_mesh->getFace(faces[0]); - BOP_Face *f1 = m_mesh->getFace(faces[1]); - if( f0->getOriginalFace() != f1->getOriginalFace() ) { -#ifdef BOP_DEBUG - cout << " " << f0 << endl; - cout << " " << f1 << endl; -#endif - eindexs[ecount++] = (*it); - } - } - } - if(ecount == 2) { -#ifdef BOP_DEBUG - cout << " edge indexes are " << eindexs[0]; - cout << " and " << eindexs[1] << endl; -#endif - BOP_Edge *edge = m_mesh->getEdge(eindexs[0]); - BOP_Index N = edge->getVertex1(); - if(N == v) N = edge->getVertex2(); -#ifdef BOP_DEBUG - cout << " ## OK, replace "<<v<<" with "<<N << endl; -#endif - mergeVertex(ff , v, N ); - mergeVertex(fb , v, N ); -// now remove v and its edges - vert->setTAG(BROKEN); - for(BOP_IT_Indexs it = edges.begin(); it != edges.end(); - ++it ) { - BOP_Edge *tedge = m_mesh->getEdge(*it); - tedge->setUsed(false); - } - didMerge = true; - } -#ifdef BOP_DEBUG - else { - cout << " HUH: ecount was " << ecount << endl; - } -#endif - } - break; - default: - break; - } - } - } - - return didMerge; -} - -void BOP_Merge2::mergeVertex(BOP_Faces &faces, BOP_Index v1, BOP_Index v2) -{ - for(BOP_IT_Faces face=faces.begin();face!=faces.end();face++) { - if( (*face)->size() == 3) - mergeVertex((BOP_Face3 *) *face, v1, v2); - else - mergeVertex((BOP_Face4 *) *face, v1, v2); - (*face)->setTAG(BROKEN); -#ifdef BOP_DEBUG - cout << " breaking " << (*face) << endl; -#endif - } -} - -/* - * Remove a face from the mesh and from each edges's face list - */ - -static void deleteFace(BOP_Mesh *m, BOP_Face *face) -{ - BOP_Index l2 = face->getVertex(0); - BOP_Faces faces = m->getFaces(); - for(int i = face->size(); i-- ; ) { - BOP_Indexs edges = m->getVertex(l2)->getEdges(); - BOP_Index l1 = face->getVertex(i); - for(BOP_IT_Indexs it1 = edges.begin(); it1 != edges.end(); ++it1 ) { - BOP_Edge *edge = m->getEdge(*it1); - if( ( edge->getVertex1() == l1 && edge->getVertex2() == l2 ) || - ( edge->getVertex1() == l2 && edge->getVertex2() == l1 ) ) { - BOP_Indexs ef = edge->getFaces(); - for(BOP_IT_Indexs it = ef.begin(); it != ef.end(); ++it ) { - if( m->getFace(*it) == face) { - edge->removeFace(*it); - break; - } - } - break; - } - } - l2 = l1; - } - face->setTAG(BROKEN); -} - -void BOP_Merge2::mergeVertex(BOP_Face3 *face, BOP_Index v1, BOP_Index v2) -{ - BOP_Index next, prev; - face->getNeighbours(v1,prev,next); - - // if new vertex is not already in the tri, make a new tri - if( prev != v2 && next != v2 ) { - m_mesh->addFace( new BOP_Face3(prev,v2,next, - face->getPlane(),face->getOriginalFace()) ); -#ifdef BOP_DEBUG - cout << "mv3: add " << prev << "," << v2 << "," << next << endl; - } else { - cout << "mv3: vertex already in tri: doing nothing" << endl; -#endif - } - deleteFace(m_mesh, face); -} - -void BOP_Merge2::mergeVertex(BOP_Face4 *face, BOP_Index v1, BOP_Index v2) -{ - BOP_Index next, prev, opp; - face->getNeighbours(v1,prev,next,opp); - - // if new vertex is already in the quad, replace quad with new tri - if( prev == v2 || next == v2 ) { - m_mesh->addFace( new BOP_Face3(prev,next,opp, - face->getPlane(),face->getOriginalFace()) ); -#ifdef BOP_DEBUG - cout << "mv4a: add " << prev << "," << next << "," << opp << endl; -#endif - } - // otherwise make a new quad - else { - m_mesh->addFace( new BOP_Face4(prev,v2,next,opp, - face->getPlane(),face->getOriginalFace()) ); -#ifdef BOP_DEBUG - cout << "mv4b: add "<<prev<<","<<v2<<","<<next<<","<<opp<<endl; -#endif - } - deleteFace(m_mesh, face); -} - -// #define OLD_QUAD - -/** - * Simplifies the mesh, merging the pairs of triangles that come frome the - * same original face and define a quad. - * @return true if a quad was added, false otherwise - */ -bool BOP_Merge2::createQuads() -{ - - BOP_Faces quads; - - // Get mesh faces - BOP_Faces faces = m_mesh->getFaces(); - - // Merge mesh triangles - const BOP_IT_Faces facesIEnd = (faces.end()-1); - const BOP_IT_Faces facesJEnd = faces.end(); - for(BOP_IT_Faces faceI=faces.begin();faceI!=facesIEnd;faceI++) { -#ifdef OLD_QUAD - if ((*faceI)->getTAG() == BROKEN || (*faceI)->size() != 3) continue; - for(BOP_IT_Faces faceJ=(faceI+1);faceJ!=facesJEnd;faceJ++) { - if ((*faceJ)->getTAG() == BROKEN || (*faceJ)->size() != 3 || - (*faceJ)->getOriginalFace() != (*faceI)->getOriginalFace()) continue; - - - BOP_Face *faceK = createQuad((BOP_Face3*)*faceI,(BOP_Face3*)*faceJ); - if (faceK != NULL) { - // Set triangles to BROKEN - deleteFace(m_mesh, *faceI); - deleteFace(m_mesh, *faceJ); -#ifdef BOP_DEBUG - cout << "createQuad: del " << *faceI << endl; - cout << "createQuad: del " << *faceJ << endl; - cout << "createQuad: add " << faceK << endl; -#endif - quads.push_back(faceK); - break; - } - } -#else - if ((*faceI)->getTAG() == BROKEN ) continue; - for(BOP_IT_Faces faceJ=(faceI+1);faceJ!=facesJEnd;faceJ++) { - if ((*faceJ)->getTAG() == BROKEN || - (*faceJ)->getOriginalFace() != (*faceI)->getOriginalFace()) continue; - - BOP_Face *faceK = NULL; - if((*faceI)->size() == 3) { - if((*faceJ)->size() == 3) - faceK = createQuad((BOP_Face3*)*faceI,(BOP_Face3*)*faceJ); - else - faceK = createQuad((BOP_Face3*)*faceI,(BOP_Face4*)*faceJ); - } else { - if((*faceJ)->size() == 3) - faceK = createQuad((BOP_Face3*)*faceJ,(BOP_Face4*)*faceI); - else - faceK = createQuad((BOP_Face4*)*faceI,(BOP_Face4*)*faceJ); - } - - if (faceK != NULL) { - // Set triangles to BROKEN - deleteFace(m_mesh, *faceI); - deleteFace(m_mesh, *faceJ); -#ifdef BOP_DEBUG - cout << "createQuad: del " << *faceI << endl; - cout << "createQuad: del " << *faceJ << endl; - cout << "createQuad: add " << faceK << endl; -#endif - quads.push_back(faceK); - break; - } - } -#endif - } - - // Add quads to mesh - const BOP_IT_Faces quadsEnd = quads.end(); - for(BOP_IT_Faces quad=quads.begin();quad!=quadsEnd;quad++) m_mesh->addFace(*quad); - return (quads.size() > 0); -} - -/** - * Returns a new quad (convex) from the merge of two triangles that share the - * vertex index v. - * @param faceI mesh triangle - * @param faceJ mesh triangle - * @param v vertex index shared by both triangles - * @return a new convex quad if the merge is possible - */ -BOP_Face* BOP_Merge2::createQuad(BOP_Face3 *faceI, BOP_Face3 *faceJ) -{ - // Test if both triangles share a vertex index - BOP_Index v; - unsigned int i; - for(i=0;i<3 ;i++) { - v = faceI->getVertex(i); - if( faceJ->containsVertex(v) ) break; - } - if (i == 3) return NULL; - - BOP_Face *faceK = NULL; - - // Get faces data - BOP_Index prevI, nextI, prevJ, nextJ; - faceI->getNeighbours(v,prevI,nextI); - faceJ->getNeighbours(v,prevJ,nextJ); - MT_Point3 vertex = m_mesh->getVertex(v)->getPoint(); - MT_Point3 vPrevI = m_mesh->getVertex(prevI)->getPoint(); - MT_Point3 vNextI = m_mesh->getVertex(nextI)->getPoint(); - MT_Point3 vPrevJ = m_mesh->getVertex(prevJ)->getPoint(); - MT_Point3 vNextJ = m_mesh->getVertex(nextJ)->getPoint(); - - // Quad test - if (prevI == nextJ) { - if (!BOP_collinear(vNextI,vertex,vPrevJ) && !BOP_collinear(vNextI,vPrevI,vPrevJ) && - BOP_convex(vertex,vNextI,vPrevI,vPrevJ)) { - faceK = new BOP_Face4(v,nextI,prevI,prevJ,faceI->getPlane(),faceI->getOriginalFace()); - faceK->setTAG(faceI->getTAG()); - BOP_Index edge; - m_mesh->getIndexEdge(v,prevI,edge); - m_mesh->getVertex(v)->removeEdge(edge); - m_mesh->getVertex(prevI)->removeEdge(edge); - } - } - else if (nextI == prevJ) { - if (!BOP_collinear(vPrevI,vertex,vNextJ) && !BOP_collinear(vPrevI,vNextI,vNextJ) && - BOP_convex(vertex,vNextJ,vNextI,vPrevI)) { - faceK = new BOP_Face4(v,nextJ,nextI,prevI,faceI->getPlane(),faceI->getOriginalFace()); - faceK->setTAG(faceI->getTAG()); - BOP_Index edge; - m_mesh->getIndexEdge(v,nextI,edge); - m_mesh->getVertex(v)->removeEdge(edge); - m_mesh->getVertex(nextI)->removeEdge(edge); - } - } - return faceK; -} - -/** - * Returns a new quad (convex) from the merge of two triangles that share the - * vertex index v. - * @param faceI mesh triangle - * @param faceJ mesh triangle - * @param v vertex index shared by both triangles - * @return a new convex quad if the merge is possible - */ -BOP_Face* BOP_Merge2::createQuad(BOP_Face3 *faceI, BOP_Face4 *faceJ) -{ - // Test if triangle and quad share a vertex index - BOP_Index v; - unsigned int i; - for(i=0;i<3 ;i++) { - v = faceI->getVertex(i); - if( faceJ->containsVertex(v) ) break; - } - if (i == 3) return NULL; - - BOP_Face *faceK = NULL; - - // Get faces data - BOP_Index prevI, nextI, prevJ, nextJ, oppJ; - faceI->getNeighbours(v,prevI,nextI); - faceJ->getNeighbours(v,prevJ,nextJ,oppJ); - - // Quad test - BOP_Index edge; - if (nextI == prevJ) { - if (prevI == nextJ) { // v is in center - faceK = new BOP_Face3(nextJ,oppJ,prevJ,faceI->getPlane(),faceI->getOriginalFace()); - faceK->setTAG(faceI->getTAG()); - m_mesh->getIndexEdge(v,prevI,edge); - m_mesh->getVertex(v)->removeEdge(edge); - m_mesh->getVertex(prevI)->removeEdge(edge); - m_mesh->getIndexEdge(v,nextI,edge); - m_mesh->getVertex(v)->removeEdge(edge); - m_mesh->getVertex(nextI)->removeEdge(edge); - freeVerts(v, m_mesh->getVertex(v)); - } else if (prevI == oppJ) { // nextI is in center - faceK = new BOP_Face3(v,nextJ,oppJ,faceI->getPlane(),faceI->getOriginalFace()); - faceK->setTAG(faceI->getTAG()); - m_mesh->getIndexEdge(v,nextI,edge); - m_mesh->getVertex(v)->removeEdge(edge); - m_mesh->getVertex(nextI)->removeEdge(edge); - m_mesh->getIndexEdge(prevI,nextI,edge); - m_mesh->getVertex(prevI)->removeEdge(edge); - m_mesh->getVertex(nextI)->removeEdge(edge); - freeVerts(nextI, m_mesh->getVertex(nextI)); - } - } else if (nextI == oppJ && prevI == nextJ ) { // prevI is in center - faceK = new BOP_Face3(prevJ,v,oppJ,faceI->getPlane(),faceI->getOriginalFace()); - faceK->setTAG(faceI->getTAG()); - m_mesh->getIndexEdge(v,prevI,edge); - m_mesh->getVertex(v)->removeEdge(edge); - m_mesh->getVertex(prevI)->removeEdge(edge); - m_mesh->getIndexEdge(nextI,prevI,edge); - m_mesh->getVertex(nextI)->removeEdge(edge); - m_mesh->getVertex(prevI)->removeEdge(edge); - freeVerts(prevI, m_mesh->getVertex(prevI)); - } - return faceK; -} - -/** - * Returns a new quad (convex) from the merge of two triangles that share the - * vertex index v. - * @param faceI mesh triangle - * @param faceJ mesh triangle - * @param v vertex index shared by both triangles - * @return a new convex quad if the merge is possible - */ -BOP_Face* BOP_Merge2::createQuad(BOP_Face4 *faceI, BOP_Face4 *faceJ) -{ - BOP_Face *faceK = NULL; - // - // Test if both quads share a vertex index - // - BOP_Index v; - unsigned int i; - for(i=0;i<4 ;i++) { - v = faceI->getVertex(i); - if( faceJ->containsVertex(v) ) break; - } - if (i == 3) return NULL; - - - // Get faces data - BOP_Index prevI, nextI, oppI, prevJ, nextJ, oppJ; - faceI->getNeighbours(v,prevI,nextI,oppI); - faceJ->getNeighbours(v,prevJ,nextJ,oppJ); - - // Quad test - BOP_Index edge; - if (nextI == prevJ) { - if (prevI == nextJ) { // v is in center - faceK = new BOP_Face4(nextI,oppI,nextJ,oppJ,faceI->getPlane(),faceI->getOriginalFace()); - faceK->setTAG(faceI->getTAG()); - m_mesh->getIndexEdge(v,prevI,edge); - m_mesh->getVertex(v)->removeEdge(edge); - m_mesh->getVertex(prevI)->removeEdge(edge); - m_mesh->getIndexEdge(v,nextI,edge); - m_mesh->getVertex(v)->removeEdge(edge); - m_mesh->getVertex(nextI)->removeEdge(edge); - freeVerts(v, m_mesh->getVertex(v)); - } else if (oppI == oppJ) { // nextI is in center - faceK = new BOP_Face4(v,nextJ,oppJ,prevI,faceI->getPlane(),faceI->getOriginalFace()); - faceK->setTAG(faceI->getTAG()); - m_mesh->getIndexEdge(v,nextI,edge); - m_mesh->getVertex(v)->removeEdge(edge); - m_mesh->getVertex(nextI)->removeEdge(edge); - m_mesh->getIndexEdge(prevI,nextI,edge); - m_mesh->getVertex(prevI)->removeEdge(edge); - m_mesh->getVertex(nextI)->removeEdge(edge); - freeVerts(nextI, m_mesh->getVertex(nextI)); - } - } else if (prevI == nextJ && oppI == oppJ) { // prevI is in center - faceK = new BOP_Face4(v,nextI,oppJ,prevJ,faceI->getPlane(),faceI->getOriginalFace()); - faceK->setTAG(faceI->getTAG()); - m_mesh->getIndexEdge(v,prevI,edge); - m_mesh->getVertex(v)->removeEdge(edge); - m_mesh->getVertex(prevI)->removeEdge(edge); - m_mesh->getIndexEdge(nextI,prevI,edge); - m_mesh->getVertex(nextI)->removeEdge(edge); - m_mesh->getVertex(prevI)->removeEdge(edge); - freeVerts(prevI, m_mesh->getVertex(prevI)); - } - return faceK; -} - -/** - * Returns if a index is inside a set of indexs. - * @param indexs set of indexs - * @param i index - * @return true if the index is inside the set, false otherwise - */ -bool BOP_Merge2::containsIndex(BOP_Indexs indexs, BOP_Index i) -{ - const BOP_IT_Indexs indexsEnd = indexs.end(); - for(BOP_IT_Indexs it=indexs.begin();it!=indexsEnd;it++) { - if (*it == i) return true; - } - return false; -} - -/** - * Creates a list of lists L1, L2, ... LN where - * LX = mesh faces with vertex v that come from the same original face - * @param facesByOriginalFace list of faces lists - * @param v vertex index - */ -void BOP_Merge2::getFaces(BOP_LFaces &facesByOriginalFace, BOP_Index v) -{ - // Get edges with vertex v - - BOP_Indexs edgeIndexs = m_mesh->getVertex(v)->getEdges(); - const BOP_IT_Indexs edgeEnd = edgeIndexs.end(); - for(BOP_IT_Indexs edgeIndex = edgeIndexs.begin();edgeIndex != edgeEnd;edgeIndex++) { - // For each edge, add its no broken faces to the output list - BOP_Edge* edge = m_mesh->getEdge(*edgeIndex); - BOP_Indexs faceIndexs = edge->getFaces(); - const BOP_IT_Indexs faceEnd = faceIndexs.end(); - for(BOP_IT_Indexs faceIndex=faceIndexs.begin();faceIndex!=faceEnd;faceIndex++) { - BOP_Face* face = m_mesh->getFace(*faceIndex); - if (face->getTAG() != BROKEN) { - bool found = false; - // Search if we already have created a list for the - // faces that come from the same original face - const BOP_IT_LFaces lfEnd = facesByOriginalFace.end(); - for(BOP_IT_LFaces facesByOriginalFaceX=facesByOriginalFace.begin(); - facesByOriginalFaceX!=lfEnd; facesByOriginalFaceX++) { - if (((*facesByOriginalFaceX)[0])->getOriginalFace() == face->getOriginalFace()) { - // Search that the face has not been added to the list before - for(unsigned int i = 0;i<(*facesByOriginalFaceX).size();i++) { - if ((*facesByOriginalFaceX)[i] == face) { - found = true; - break; - } - } - if (!found) { - // Add the face to the list - if (face->getTAG()==OVERLAPPED) facesByOriginalFaceX->insert(facesByOriginalFaceX->begin(),face); - else facesByOriginalFaceX->push_back(face); - found = true; - } - break; - } - } - if (!found) { - // Create a new list and add the current face - BOP_Faces facesByOriginalFaceX; - facesByOriginalFaceX.push_back(face); - facesByOriginalFace.push_back(facesByOriginalFaceX); - } - } - } - } -} - -/** - * Creates a list of lists L1, L2, ... LN where - * LX = mesh faces with vertex v that come from the same original face - * and without any of the vertices that appear before v in vertices - * @param facesByOriginalFace list of faces lists - * @param vertices vector with vertices indexs that contains v - * @param v vertex index - */ -void BOP_Merge2::getFaces(BOP_LFaces &facesByOriginalFace, BOP_Indexs vertices, BOP_Index v) -{ - // Get edges with vertex v - BOP_Indexs edgeIndexs = m_mesh->getVertex(v)->getEdges(); - const BOP_IT_Indexs edgeEnd = edgeIndexs.end(); - for(BOP_IT_Indexs edgeIndex = edgeIndexs.begin();edgeIndex != edgeEnd;edgeIndex++) { - // Foreach edge, add its no broken faces to the output list - BOP_Edge* edge = m_mesh->getEdge(*edgeIndex); - BOP_Indexs faceIndexs = edge->getFaces(); - const BOP_IT_Indexs faceEnd = faceIndexs.end(); - for(BOP_IT_Indexs faceIndex=faceIndexs.begin();faceIndex!=faceEnd;faceIndex++) { - BOP_Face* face = m_mesh->getFace(*faceIndex); - if (face->getTAG() != BROKEN) { - // Search if the face contains any of the forbidden vertices - bool found = false; - for(BOP_IT_Indexs vertex = vertices.begin();*vertex!= v;vertex++) { - if (face->containsVertex(*vertex)) { - // face contains a forbidden vertex! - found = true; - break; - } - } - if (!found) { - // Search if we already have created a list with the - // faces that come from the same original face - const BOP_IT_LFaces lfEnd = facesByOriginalFace.end(); - for(BOP_IT_LFaces facesByOriginalFaceX=facesByOriginalFace.begin(); - facesByOriginalFaceX!=lfEnd; facesByOriginalFaceX++) { - if (((*facesByOriginalFaceX)[0])->getOriginalFace() == face->getOriginalFace()) { - // Search that the face has not been added to the list before - for(unsigned int i = 0;i<(*facesByOriginalFaceX).size();i++) { - if ((*facesByOriginalFaceX)[i] == face) { - found = true; - break; - } - } - if (!found) { - // Add face to the list - if (face->getTAG()==OVERLAPPED) facesByOriginalFaceX->insert(facesByOriginalFaceX->begin(),face); - else facesByOriginalFaceX->push_back(face); - found = true; - } - break; - } - } - if (!found) { - // Create a new list and add the current face - BOP_Faces facesByOriginalFaceX; - facesByOriginalFaceX.push_back(face); - facesByOriginalFace.push_back(facesByOriginalFaceX); - } - } - } - } - } -} - -#endif /* BOP_NEW_MERGE */ diff --git a/intern/boolop/intern/BOP_Merge2.h b/intern/boolop/intern/BOP_Merge2.h deleted file mode 100644 index 71ec0702a0b..00000000000 --- a/intern/boolop/intern/BOP_Merge2.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file boolop/intern/BOP_Merge2.h - * \ingroup boolopintern - */ - - -#ifndef __BOP_MERGE2_H__ -#define __BOP_MERGE2_H__ - -#include "BOP_Misc.h" - -#ifdef BOP_NEW_MERGE - -#include "BOP_Mesh.h" -#include "BOP_Tag.h" -#include "BOP_MathUtils.h" -#include "MEM_SmartPtr.h" - -typedef std::vector< BOP_Faces > BOP_LFaces; -typedef std::vector< BOP_Faces >::iterator BOP_IT_LFaces; - -class BOP_Merge2 { - private: - BOP_Mesh* m_mesh; - BOP_Index m_firstVertex; - static BOP_Merge2 SINGLETON; - - BOP_Merge2() {}; - bool mergeFaces(); - bool mergeFaces(BOP_Indexs &mergeVertices); - bool mergeFaces(BOP_Faces &oldFaces, BOP_Faces &newFaces, BOP_Indexs &vertices, BOP_Index v); - bool mergeFaces(BOP_Faces &faces, BOP_Faces &oldFaces, BOP_Faces &newFaces, BOP_Indexs &vertices, BOP_Index v); - BOP_Face *mergeFaces(BOP_Face *faceI, BOP_Face *faceJ, BOP_Index v); - BOP_Face *mergeFaces(BOP_Face *faceI, BOP_Face *faceJ, BOP_Indexs &pending, BOP_Index v); - BOP_Face *mergeFaces(BOP_Face3 *faceI, BOP_Face3 *faceJ, BOP_Index v); - BOP_Face *mergeFaces(BOP_Face4 *faceI, BOP_Face3 *faceJ, BOP_Index v); - BOP_Face *mergeFaces(BOP_Face4 *faceI, BOP_Face3 *faceJ, BOP_Indexs &pending, BOP_Index v); - BOP_Face *mergeFaces(BOP_Face4 *faceI, BOP_Face4 *faceJ, BOP_Indexs &pending, BOP_Index v); - bool createQuads(); - bool containsIndex(BOP_Indexs indexs, BOP_Index index); - void getFaces(BOP_LFaces &facesByOriginalFace, BOP_Index v); - void getFaces(BOP_LFaces &facesByOriginalFace, BOP_Indexs vertices, BOP_Index v); - BOP_Face *createQuad(BOP_Face3 *faceI, BOP_Face3 *faceJ); - BOP_Face *createQuad(BOP_Face3 *faceI, BOP_Face4 *faceJ); - BOP_Face *createQuad(BOP_Face4 *faceI, BOP_Face4 *faceJ); - - bool mergeVertex(BOP_Face *faceI, BOP_Face *faceJ, BOP_Index v, - BOP_Indexs &mergeVertices); - bool mergeVertex(BOP_Face *faceI, BOP_Face *faceJ, BOP_Index v, - BOP_Indexs &pending, BOP_Faces &oldFaces, BOP_Faces &newFaces ); - BOP_Face *find3Neighbor(BOP_Face *faceI, BOP_Face *faceJ, - BOP_Index X, BOP_Index I, BOP_Index P, BOP_Index N ); - BOP_Face *find4Neighbor(BOP_Face *faceI, BOP_Face *faceJ, - BOP_Index X, BOP_Index I, BOP_Index P, BOP_Index N, - BOP_Face **faceL, BOP_Index &O); - BOP_Face3 *collapse(BOP_Face4 *faceC, BOP_Index X); - void mergeFaces(BOP_Face *A, BOP_Face *B, BOP_Index X, - BOP_Index I, BOP_Index N, BOP_Index P, BOP_Faces &newFaces ); - void freeVerts(BOP_Index v, BOP_Vertex *vert); - - void mergeVertex(BOP_Faces&, BOP_Index, BOP_Index); - void mergeVertex(BOP_Face3 *, BOP_Index, BOP_Index); - void mergeVertex(BOP_Face4 *, BOP_Index, BOP_Index); - void cleanup( void ); - - public: - - static BOP_Merge2 &getInstance() { - return SINGLETON; - } - - void mergeFaces(BOP_Mesh *m, BOP_Index v); -}; - -void dumpmesh(BOP_Mesh *, bool); - -#endif /* BOP_NEW_MERGE2 */ -#endif diff --git a/intern/boolop/intern/BOP_Mesh.cpp b/intern/boolop/intern/BOP_Mesh.cpp deleted file mode 100644 index 673caa3e921..00000000000 --- a/intern/boolop/intern/BOP_Mesh.cpp +++ /dev/null @@ -1,1090 +0,0 @@ -/* - * - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file boolop/intern/BOP_Mesh.cpp - * \ingroup boolopintern - */ - - -#include "BOP_Mesh.h" -#include "BOP_MathUtils.h" -#include <iostream> -#include <fstream> - -#include "MEM_guardedalloc.h" -#include "BLI_blenlib.h" - -BOP_Mesh::BOP_Mesh() -{ -#ifdef HASH -#ifdef HASH_PRINTF_DEBUG - printf ("has hashing\n"); -#endif - hash = NULL; - hashsize = 0; -#endif -} - -/** - * Destroys a mesh. - */ -BOP_Mesh::~BOP_Mesh() -{ - const BOP_IT_Vertexs vertexsEnd = m_vertexs.end(); - for(BOP_IT_Vertexs itv=m_vertexs.begin();itv!=vertexsEnd;itv++){ - delete *itv; - } - m_vertexs.clear(); - - const BOP_IT_Edges edgesEnd = m_edges.end(); - for(BOP_IT_Edges ite=m_edges.begin();ite!=edgesEnd;ite++){ - delete *ite; - } - m_edges.clear(); - - const BOP_IT_Faces facesEnd = m_faces.end(); - for(BOP_IT_Faces itf=m_faces.begin();itf!=facesEnd;itf++){ - delete *itf; - } - m_faces.clear(); - -#ifdef HASH - while( hashsize ) { - --hashsize; - BLI_freelistN( &hash[hashsize] ); - } - MEM_freeN( hash ); - hash = NULL; -#endif -} - -/** - * Adds a new vertex. - * @param p vertex point - * @return mesh vertex index - */ -BOP_Index BOP_Mesh::addVertex(MT_Point3 p) -{ - m_vertexs.push_back(new BOP_Vertex(p)); - return m_vertexs.size()-1; -} - -/** - * Adds a new edge. - * @param v1 mesh vertex index - * @param v2 mesh vertex index - * @return mesh edge index - */ -BOP_Index BOP_Mesh::addEdge(BOP_Index v1, BOP_Index v2) -{ -#ifdef HASH - /* prepare a new hash entry for the edge */ - int minv; - EdgeEntry *h = (EdgeEntry *)MEM_callocN( sizeof( EdgeEntry ), "edgehash" ); - - /* store sorted, smallest vert first */ - if( v1 < v2 ) { - minv = HASH(v1); - h->v1 = v1; - h->v2 = v2; - } else { - minv = HASH(v2); - h->v1 = v2; - h->v2 = v1; - } - h->index = m_edges.size(); - - /* if hash index larger than hash list, extend the list */ - if( minv >= hashsize ) { - int newsize = (minv + 8) & ~7; - ListBase *nhash = (ListBase *)MEM_mallocN( - newsize * sizeof( ListBase ), - "edgehashtable" ); - /* copy old entries */ - memcpy( nhash, hash, sizeof( ListBase ) * hashsize ); - /* clear new ones */ - while( hashsize < newsize ) { - nhash[hashsize].first = nhash[hashsize].last = NULL; - ++hashsize; - } - if( hash ) - MEM_freeN( hash ); - hash = nhash; - } - - /* add the entry to tail of the right hash list */ - BLI_addtail( &hash[minv], h ); -#endif - m_edges.push_back(new BOP_Edge(v1,v2)); - return m_edges.size()-1; -} - -#ifdef HASH -/** - * replace one vertex with another in the hash list - * @param o old mesh vertex index - * @param n new mesh vertex index - * @param x edge's other mesh vertex index - */ -void BOP_Mesh::rehashVertex(BOP_Index o, BOP_Index n, BOP_Index x) -{ - EdgeEntry *edge; - int minv = HASH(o); - BOP_Index v1, v2; - - /* figure out where and what to look for */ - if( o < x ) { - minv = HASH(o); - v1 = o; v2 = x; - } else { - minv = HASH(x); - v1 = x; v2 = o; - } - - /* if hash is valid, search for the match */ - if( minv < hashsize ) { - for(edge = (EdgeEntry *)hash[minv].first; - edge; edge = edge->next ) { - if(edge->v1 == v1 && edge->v2 == v2) - break; - } - - /* NULL edge == no match */ - if(!edge) { -#ifdef HASH_PRINTF_DEBUG - printf ("OOPS! didn't find edge (%d %d)\n",v1,v2); -#endif - return; - } -#ifdef HASH_PRINTF_DEBUG - printf ("found edge (%d %d)\n",v1,v2); -#endif - /* remove the edge from the old hash list */ - BLI_remlink( &hash[minv], edge ); - - /* decide where the new edge should go */ - if( n < x ) { - minv = HASH(n); - v1 = n; v2 = x; - } else { - minv = HASH(x); - edge->v1 = x; edge->v2 = n; - } - - /* if necessary, extend the hash list */ - if( minv >= hashsize ) { -#ifdef HASH_PRINTF_DEBUG - printf ("OOPS! new vertex too large! (%d->%d)\n",o,n); -#endif - int newsize = (minv + 8) & ~7; - ListBase *nhash = (ListBase *)MEM_mallocN( - newsize * sizeof( ListBase ), - "edgehashtable" ); - memcpy( nhash, hash, sizeof( ListBase ) * hashsize ); - while( hashsize < newsize ) { - nhash[hashsize].first = nhash[hashsize].last = NULL; - ++hashsize; - } - if( hash ) - MEM_freeN( hash ); - hash = nhash; - } - - /* add the entry to tail of the right hash list */ - BLI_addtail( &hash[minv], edge ); - } else { -#ifdef HASH_PRINTF_DEBUG - printf ("OOPS! hash not large enough for (%d %d)\n",minv,hashsize); -#endif - } -} -#endif - -/** - * Adds a new face. - * @param face mesh face - * @return mesh face index - */ -BOP_Index BOP_Mesh::addFace(BOP_Face *face) -{ - if (face->size()==3) - return addFace((BOP_Face3 *)face); - else - return addFace((BOP_Face4 *)face); -} - -/** - * Adds a new triangle. - * @param face mesh triangle - * @return mesh face index - */ -BOP_Index BOP_Mesh::addFace(BOP_Face3 *face) -{ - BOP_Index indexface = m_faces.size(); - - BOP_Index index1 = face->getVertex(0); - BOP_Index index2 = face->getVertex(1); - BOP_Index index3 = face->getVertex(2); - - m_faces.push_back((BOP_Face *)face); - - BOP_Index edge; - - if (!getIndexEdge(index1,index2,edge)) { - edge = addEdge(index1,index2); - getVertex(index1)->addEdge(edge); - getVertex(index2)->addEdge(edge); - } - - getEdge(edge)->addFace(indexface); - - if (!getIndexEdge(index2,index3,edge)) { - edge = addEdge(index2,index3); - getVertex(index2)->addEdge(edge); - getVertex(index3)->addEdge(edge); - } - - getEdge(edge)->addFace(indexface); - - if (!getIndexEdge(index3,index1,edge)) { - edge = addEdge(index3,index1); - getVertex(index3)->addEdge(edge); - getVertex(index1)->addEdge(edge); - } - - getEdge(edge)->addFace(indexface); - - if ((index1 == index2) || (index1 == index3) || (index2 == index3)) - face->setTAG(BROKEN); - - return indexface; -} - -/** - * Adds a new quad. - * @param face mesh quad - * @return mesh face index - */ -BOP_Index BOP_Mesh::addFace(BOP_Face4 *face) -{ - m_faces.push_back((BOP_Face *)face); - BOP_Index indexface = m_faces.size()-1; - - BOP_Index index1 = face->getVertex(0); - BOP_Index index2 = face->getVertex(1); - BOP_Index index3 = face->getVertex(2); - BOP_Index index4 = face->getVertex(3); - - BOP_Index edge; - - if (!getIndexEdge(index1,index2,edge)) { - edge = addEdge(index1,index2); - getVertex(index1)->addEdge(edge); - getVertex(index2)->addEdge(edge); - } - - getEdge(edge)->addFace(indexface); - - if (!getIndexEdge(index2,index3,edge)) { - edge = addEdge(index2,index3); - getVertex(index2)->addEdge(edge); - getVertex(index3)->addEdge(edge); - } - - getEdge(edge)->addFace(indexface); - - if (!getIndexEdge(index3,index4,edge)) { - edge = addEdge(index3,index4); - getVertex(index3)->addEdge(edge); - getVertex(index4)->addEdge(edge); - } - - getEdge(edge)->addFace(indexface); - - if (!getIndexEdge(index4,index1,edge)) { - edge = addEdge(index4,index1); - getVertex(index4)->addEdge(edge); - getVertex(index1)->addEdge(edge); - } - - getEdge(edge)->addFace(indexface); - - if ((index1 == index2) || (index1 == index3) || (index1 == index4) || - (index2 == index3) || (index2 == index4) || (index3 == index4)) - face->setTAG(BROKEN); - - return m_faces.size()-1; -} - -/** - * Returns if a faces set contains the specified face. - * @param faces faces set - * @param face face - * @return true if the set contains the specified face - */ -bool BOP_Mesh::containsFace(BOP_Faces *faces, BOP_Face *face) -{ - const BOP_IT_Faces facesEnd = faces->end(); - for(BOP_IT_Faces it = faces->begin();it!=facesEnd;it++) { - if (face == *it) - return true; - } - - return false; -} -/** - * Returns the first edge with the specified vertex index from a list of edge indexs. - * @param edges edge indexs - * @param v vertex index - * @return first edge with the specified vertex index, NULL otherwise - */ -BOP_Edge* BOP_Mesh::getEdge(BOP_Indexs edges, BOP_Index v) -{ - const BOP_IT_Indexs edgesEnd = edges.end(); - for(BOP_IT_Indexs it=edges.begin();it!=edgesEnd;it++){ - BOP_Edge *edge = m_edges[*it]; - if ((edge->getVertex1() == v) || (edge->getVertex2() == v)) - return edge; - } - return NULL; -} - -/** - * Returns the mesh edge with the specified vertex indexs. - * @param v1 vertex index - * @param v2 vertex index - * @return mesh edge with the specified vertex indexs, NULL otherwise - */ -BOP_Edge* BOP_Mesh::getEdge(BOP_Index v1, BOP_Index v2) -{ -#ifdef HASH - int minv; - EdgeEntry *edge; - - /* figure out where and what to search for */ - if( v1 < v2 ) { - minv = HASH(v1); - } else { - minv = HASH(v2); - BOP_Index tmp = v1; - v1 = v2; - v2 = tmp; - } - - /* if hash index valid, search the list and return match if found */ - if( minv < hashsize ) { - for(edge = (EdgeEntry *)hash[minv].first; - edge; edge = edge->next ) { - if(edge->v1 == v1 && edge->v2 == v2) - return m_edges[edge->index]; - } - } -#else - const BOP_IT_Edges edgesEnd = m_edges.end(); - for(BOP_IT_Edges edge=m_edges.begin();edge!=edgesEnd;edge++) { - if (((*edge)->getVertex1() == v1 && (*edge)->getVertex2() == v2) || - ((*edge)->getVertex1() == v2 && (*edge)->getVertex2() == v1)) - return *edge; - } -#endif - return NULL; -} - -/** - * Returns the mesh edge index with the specified vertex indexs. - * @param v1 vertex index - * @param v2 vertex index - * @param e edge index with the specified vertex indexs - * @return true if there is a mesh edge with the specified vertex indexs, false otherwise - */ -bool BOP_Mesh::getIndexEdge(BOP_Index v1, BOP_Index v2, BOP_Index &e) -{ -#ifdef HASH - int minv; - EdgeEntry *edge; - - /* figure out what and where to look */ - if( v1 < v2 ) { - minv = HASH(v1); - } else { - minv = HASH(v2); - BOP_Index tmp = v1; - v1 = v2; - v2 = tmp; - } - - /* if hash index is valid, look for a match */ - if( minv < hashsize ) { - for(edge = (EdgeEntry *)hash[minv].first; - edge; edge = edge->next ) { - if(edge->v1 == v1 && edge->v2 == v2) - break; - } - - /* edge != NULL means match */ - if(edge) { -#ifdef HASH_PRINTF_DEBUG - printf ("found edge (%d %d)\n",v1,v2); -#endif - e = edge->index; -#ifdef BOP_NEW_MERGE - if( m_edges[e]->getUsed() == false ) { - m_edges[e]->setUsed(true); - m_vertexs[v1]->addEdge(e); - m_vertexs[v2]->addEdge(e); - } -#endif - return true; - } -#ifdef HASH_PRINTF_DEBUG - else - printf ("didn't find edge (%d %d)\n",v1,v2); -#endif - } -#else - BOP_Index pos=0; - const BOP_IT_Edges edgesEnd = m_edges.end(); - for(BOP_IT_Edges edge=m_edges.begin();edge!=edgesEnd;edge++,pos++) { - if (((*edge)->getVertex1() == v1 && (*edge)->getVertex2() == v2) || - ((*edge)->getVertex1() == v2 && (*edge)->getVertex2() == v1)){ - e = pos; - return true; - } - } -#endif - return false; -} - -/** - * Returns the mesh edge on the specified face and relative edge index. - * @param face mesh face - * @param edge face relative edge index - * @return mesh edge on the specified face and relative index, NULL otherwise - */ -BOP_Edge* BOP_Mesh::getEdge(BOP_Face *face, unsigned int edge) -{ - if (face->size()==3) - return getEdge((BOP_Face3 *)face,edge); - else - return getEdge((BOP_Face4 *)face,edge); -} - -/** - * Returns the mesh edge on the specified triangle and relative edge index. - * @param face mesh triangle - * @param edge face relative edge index - * @return mesh edge on the specified triangle and relative index, NULL otherwise - */ -BOP_Edge* BOP_Mesh::getEdge(BOP_Face3 *face, unsigned int edge) -{ - switch(edge){ - case 1: - return getEdge(m_vertexs[face->getVertex(0)]->getEdges(),face->getVertex(1)); - case 2: - return getEdge(m_vertexs[face->getVertex(1)]->getEdges(),face->getVertex(2)); - case 3: - return getEdge(m_vertexs[face->getVertex(2)]->getEdges(),face->getVertex(0)); - }; - - return NULL; -} - -/** - * Returns the mesh edge on the specified quad and relative edge index. - * @param face mesh quad - * @param edge face relative edge index - * @return mesh edge on the specified quad and relative index, NULL otherwise - */ -BOP_Edge * BOP_Mesh::getEdge(BOP_Face4 *face, unsigned int edge) -{ - switch(edge){ - case 1: - return getEdge(m_vertexs[face->getVertex(0)]->getEdges(),face->getVertex(1)); - case 2: - return getEdge(m_vertexs[face->getVertex(1)]->getEdges(),face->getVertex(2)); - case 3: - return getEdge(m_vertexs[face->getVertex(2)]->getEdges(),face->getVertex(3)); - case 4: - return getEdge(m_vertexs[face->getVertex(3)]->getEdges(),face->getVertex(0)); - }; - - return NULL; -} - -/** - * Returns the mesh face with the specified vertex indexs. - * @param v1 vertex index - * @param v2 vertex index - * @param v3 vertex index - * @return mesh edge with the specified vertex indexs, NULL otherwise - */ -BOP_Face* BOP_Mesh::getFace(BOP_Index v1, BOP_Index v2, BOP_Index v3) -{ - const BOP_IT_Faces facesEnd = m_faces.end(); - for(BOP_IT_Faces face=m_faces.begin();face!=facesEnd;face++) { - if ((*face)->containsVertex(v1) && (*face)->containsVertex(v2) && - (*face)->containsVertex(v3)) - return (*face); - } - return NULL; -} - -/** - * Returns the mesh face index with the specified vertex indexs. - * @param v1 vertex index - * @param v2 vertex index - * @param v3 vertex index - * @param f face index with the specified vertex indexs - * @return true if there is a mesh face with the specified vertex indexs, false otherwise - */ -bool BOP_Mesh::getIndexFace(BOP_Index v1, BOP_Index v2, BOP_Index v3, BOP_Index &f) -{ - BOP_Index pos=0; - const BOP_IT_Faces facesEnd = m_faces.end(); - for(BOP_IT_Faces face=m_faces.begin();face!=facesEnd;face++,pos++) { - if ((*face)->containsVertex(v1) && (*face)->containsVertex(v2) && - (*face)->containsVertex(v3)){ - f = pos; - return true; - } - } - return false; -} - -/** - * Returns the vertices set of this mesh. - * @return vertices set - */ -BOP_Vertexs &BOP_Mesh::getVertexs() -{ - return m_vertexs; -} - -/** - * Returns the edges set of this mesh. - * @return edges set - */ -BOP_Edges &BOP_Mesh::getEdges() -{ - return m_edges; -} - -/** - * Returns the faces set of this mesh. - * @return faces set - */ -BOP_Faces &BOP_Mesh::getFaces() -{ - return m_faces; -} - -/** - * Returns the mesh vertex with the specified index. - * @param i vertex index - * @return vertex with the specified index - */ -BOP_Vertex* BOP_Mesh::getVertex(BOP_Index i) -{ - return m_vertexs[i]; -} - -/** - * Returns the mesh edge with the specified index. - * @param i edge index - * @return edge with the specified index - */ -BOP_Edge* BOP_Mesh::getEdge(BOP_Index i) -{ - return m_edges[i]; -} - -/** - * Returns the mesh face with the specified index. - * @param i face index - * @return face with the specified index - */ -BOP_Face* BOP_Mesh::getFace(BOP_Index i) -{ - return m_faces[i]; -} - -/** - * Returns the number of vertices of this mesh. - * @return number of vertices - */ -unsigned int BOP_Mesh::getNumVertexs() -{ - return m_vertexs.size(); -} - -/** - * Returns the number of edges of this mesh. - * @return number of edges - */ -unsigned int BOP_Mesh::getNumEdges() -{ - return m_edges.size(); -} - -/** - * Returns the number of faces of this mesh. - * @return number of faces - */ -unsigned int BOP_Mesh::getNumFaces() -{ - return m_faces.size(); -} - -/** - * Returns the number of vertices of this mesh with the specified tag. - * @return number of vertices with the specified tag - */ -unsigned int BOP_Mesh::getNumVertexs(BOP_TAG tag) -{ - unsigned int count = 0; - const BOP_IT_Vertexs vertexsEnd = m_vertexs.end(); - for(BOP_IT_Vertexs vertex=m_vertexs.begin();vertex!=vertexsEnd;vertex++) { - if ((*vertex)->getTAG() == tag) count++; - } - return count; -} -/** - * Returns the number of faces of this mesh with the specified tag. - * @return number of faces with the specified tag - */ -unsigned int BOP_Mesh::getNumFaces(BOP_TAG tag) -{ - unsigned int count = 0; - const BOP_IT_Faces facesEnd = m_faces.end(); - for(BOP_IT_Faces face=m_faces.begin();face!=facesEnd;face++) { - if ((*face)->getTAG() == tag) count++; - } - return count; -} - -/** - * Marks faces which bad edges as BROKEN (invalid face, no further processing). - * @param edge edge which is being replaced - * @param mesh mesh containing faces - */ - -static void removeBrokenFaces( BOP_Edge *edge, BOP_Mesh *mesh ) -{ - BOP_Faces m_faces = mesh->getFaces(); - - BOP_Indexs edgeFaces = edge->getFaces(); - const BOP_IT_Indexs edgeFacesEnd = edgeFaces.end(); - for(BOP_IT_Indexs idxFace=edgeFaces.begin();idxFace!=edgeFacesEnd; - idxFace++) - m_faces[*idxFace]->setTAG(BROKEN); -} - -/** - * Replaces a vertex index. - * @param oldIndex old vertex index - * @param newIndex new vertex index - */ -BOP_Index BOP_Mesh::replaceVertexIndex(BOP_Index oldIndex, BOP_Index newIndex) -{ - BOP_IT_Indexs oldEdgeIndex; - if (oldIndex==newIndex) return newIndex; - - // Update faces, edges and vertices - BOP_Vertex *oldVertex = m_vertexs[oldIndex]; - BOP_Vertex *newVertex = m_vertexs[newIndex]; - BOP_Indexs oldEdges = oldVertex->getEdges(); - - // Update faces to the newIndex - BOP_IT_Indexs oldEdgesEnd = oldEdges.end(); - for(oldEdgeIndex=oldEdges.begin();oldEdgeIndex!=oldEdgesEnd; - oldEdgeIndex++) { - BOP_Edge *edge = m_edges[*oldEdgeIndex]; - if ((edge->getVertex1()==oldIndex && edge->getVertex2()==newIndex) || - (edge->getVertex2()==oldIndex && edge->getVertex1()==newIndex)) { - // Remove old edge ==> set edge faces to BROKEN - removeBrokenFaces( edge, this ); - oldVertex->removeEdge(*oldEdgeIndex); - newVertex->removeEdge(*oldEdgeIndex); - } - else { - BOP_Indexs faces = edge->getFaces(); - const BOP_IT_Indexs facesEnd = faces.end(); - for(BOP_IT_Indexs face=faces.begin();face!=facesEnd;face++) { - if (m_faces[*face]->getTAG()!=BROKEN) - m_faces[*face]->replaceVertexIndex(oldIndex,newIndex); - } - } - } - - oldEdgesEnd = oldEdges.end(); - for(oldEdgeIndex=oldEdges.begin();oldEdgeIndex!=oldEdgesEnd; - oldEdgeIndex++) { - BOP_Edge * edge = m_edges[*oldEdgeIndex]; - BOP_Edge * edge2; - BOP_Index v1 = edge->getVertex1(); - - v1 = (v1==oldIndex?edge->getVertex2():v1); - if ((edge2 = getEdge(newIndex,v1)) == NULL) { - edge->replaceVertexIndex(oldIndex,newIndex); - if ( edge->getVertex1() == edge->getVertex2() ) { - removeBrokenFaces( edge, this ); - oldVertex->removeEdge(*oldEdgeIndex); - } -#ifdef HASH - rehashVertex(oldIndex,newIndex,v1); -#endif - newVertex->addEdge(*oldEdgeIndex); - } - else { - BOP_Indexs faces = edge->getFaces(); - const BOP_IT_Indexs facesEnd = faces.end(); - for(BOP_IT_Indexs f=faces.begin();f!=facesEnd;f++) { - if (m_faces[*f]->getTAG()!=BROKEN) - edge2->addFace(*f); - } - BOP_Vertex *oppositeVertex = m_vertexs[v1]; - oppositeVertex->removeEdge(*oldEdgeIndex); - edge->replaceVertexIndex(oldIndex,newIndex); - if ( edge->getVertex1() == edge->getVertex2() ) { - removeBrokenFaces( edge, this ); - oldVertex->removeEdge(*oldEdgeIndex); - newVertex->removeEdge(*oldEdgeIndex); - } -#ifdef HASH - rehashVertex(oldIndex,newIndex,v1); -#endif - } - } - oldVertex->setTAG(BROKEN); - - return newIndex; -} - -bool BOP_Mesh::isClosedMesh() -{ - for(unsigned int i=0; i<m_edges.size(); i++) { - BOP_Edge *edge = m_edges[i]; - BOP_Indexs faces = edge->getFaces(); - unsigned int count = 0; - const BOP_IT_Indexs facesEnd = faces.end(); - for(BOP_IT_Indexs it = faces.begin();it!=facesEnd;it++) { - if (m_faces[*it]->getTAG()!=BROKEN) - count++; - } - - if ((count%2)!=0) return false; - } - - return true; -} - - -#ifdef BOP_DEBUG -/****************************************************************************** - * DEBUG METHODS * - * This functions are used to test the mesh state and debug program errors. * - ******************************************************************************/ - -/** - * print - */ -void BOP_Mesh::print() -{ - unsigned int i; - cout << "--Faces--" << endl; - for(i=0;i<m_faces.size();i++){ - cout << "Face " << i << ": " << m_faces[i] << endl; - } - - cout << "--Vertices--" << endl; - for(i=0;i<m_vertexs.size();i++){ - cout << "Point " << i << ": " << m_vertexs[i]->getPoint() << endl; - } -} - -/** - * printFormat - */ -void BOP_Mesh::printFormat(BOP_Faces *faces) -{ - if (faces->size()) { - for(unsigned int it=1;it<faces->size();it++) { - if ((*faces)[it]->getTAG()!=BROKEN) { - cout << m_vertexs[(*faces)[it]->getVertex(0)]->getPoint() << " "; - cout << m_vertexs[(*faces)[it]->getVertex(1)]->getPoint() << " "; - cout << m_vertexs[(*faces)[it]->getVertex(2)]->getPoint() << endl; - } - } - } -} - -/** - * saveFormat - */ -void BOP_Mesh::saveFormat(BOP_Faces *faces,char *filename) -{ - ofstream fout(filename); - - if (!fout.is_open()) { - cerr << "BOP_Mesh::saveFormat Error: Could not create file." << endl; - return; - } - - unsigned int count = 0; - if (faces->size()) { - for(unsigned int it=0;it<faces->size();it++) { - if ((*faces)[it]->getTAG()!=BROKEN) { - count++; - } - } - } - - fout << count << endl; - if (faces->size()) { - for(unsigned int it=0;it<faces->size();it++) { - if ((*faces)[it]->getTAG()!=BROKEN){ - fout << m_vertexs[(*faces)[it]->getVertex(0)]->getPoint() << " "; - fout << m_vertexs[(*faces)[it]->getVertex(1)]->getPoint() << " "; - fout << m_vertexs[(*faces)[it]->getVertex(2)]->getPoint() << endl; - } - } - } - - fout.close(); -} - -/** - * printFormat - */ -void BOP_Mesh::printFormat() -{ - cout << "--Vertices--" << endl; - if (m_vertexs.size()>0) { - cout << "{" << m_vertexs[0]->getPoint().x() << ","; - cout << m_vertexs[0]->getPoint().y() << ","; - cout << m_vertexs[0]->getPoint().z() << "}"; - for(unsigned int i=1;i<m_vertexs.size();i++) { - cout << ",{" << m_vertexs[i]->getPoint().x() << ","; - cout << m_vertexs[i]->getPoint().y() << ","; - cout << m_vertexs[i]->getPoint().z() << "}"; - } - cout << endl; - } - - cout << "--Faces--" << endl; - if (m_faces.size()>0) { - cout << "{" << m_faces[0]->getVertex(0) << ","; - cout << m_faces[0]->getVertex(1) << "," << m_faces[0]->getVertex(2) << "}"; - for(unsigned int i=1;i<m_faces.size();i++) { - cout << ",{" << m_faces[i]->getVertex(0) << ","; - cout << m_faces[i]->getVertex(1) << "," << m_faces[i]->getVertex(2) << "}"; - } - cout << endl; - } -} - -/** - * printFace - */ -void BOP_Mesh::printFace(BOP_Face *face, int col) -{ - cout << "--Face" << endl; - cout << m_vertexs[face->getVertex(0)]->getPoint(); - cout << " " << m_vertexs[face->getVertex(1)]->getPoint(); - cout << " " << m_vertexs[face->getVertex(2)]->getPoint(); - if (face->size()==4) - cout << " " << m_vertexs[face->getVertex(3)]->getPoint(); - cout << " " << col << endl; -} - -/** - * testMesh - */ -void BOP_Mesh::testMesh() -{ - - BOP_Face* cares[10]; - unsigned int nedges=0,i; - for(i=0;i<m_edges.size();i++) { - BOP_Edge *edge = m_edges[i]; - BOP_Indexs faces = edge->getFaces(); - unsigned int count = 0; - const BOP_IT_Indexs facesEnd = faces.end(); - for(BOP_IT_Indexs it = faces.begin();it!=facesEnd;it++) { - if (m_faces[*it]->getTAG()!=BROKEN) { - cares[count] = m_faces[*it]; - count++; - - } - } - - if ((count%2)!=0) nedges++; - } - if (nedges) - cout << nedges << " wrong edges." << endl; - else - cout << "well edges." << endl; - - unsigned int duplFaces = 0; - unsigned int wrongFaces = 0; - for(i=0;i<m_faces.size();i++){ - BOP_Face *faceI = m_faces[i]; - if (faceI->getTAG()==BROKEN) - continue; - - if (testFace(faceI)){ - wrongFaces++; - cout << "Wrong Face: " << faceI << endl; - } - - for(unsigned int j=i+1;j<m_faces.size();j++){ - BOP_Face *faceJ = m_faces[j]; - - if (faceJ->getTAG()==BROKEN) - continue; - - if (testFaces(faceI,faceJ)){ - duplFaces++; - cout << "Duplicate FaceI: " << faceI << endl; - cout << "Duplicate FaceJ: " << faceJ << endl; - } - } - } - - cout << duplFaces << " duplicate faces." << endl; - cout << wrongFaces << " wrong faces." << endl; -} - -/** - * testFace - */ -bool BOP_Mesh::testFace(BOP_Face *face){ - - for(unsigned int i=0;i<face->size();i++){ - for(unsigned int j=i+1;j<face->size();j++){ - if (face->getVertex(i)==face->getVertex(j)) - return true; - } - } - - return false; -} - -/** - * testFaces - */ -bool BOP_Mesh::testFaces(BOP_Face *faceI, BOP_Face *faceJ){ - - if (faceI->size()<faceJ->size()){ - for(unsigned int i=0;i<faceI->size();i++){ - if (!faceJ->containsVertex(faceI->getVertex(i))) - return false; - } - //faceI->setTAG(BROKEN); - } - else{ - for(unsigned int i=0;i<faceJ->size();i++){ - if (!faceI->containsVertex(faceJ->getVertex(i))) - return false; - } - //faceJ->setTAG(BROKEN); - } - - return true; -} - -/** - * testPlane - */ -void BOP_Mesh::testPlane(BOP_Face *face) -{ - MT_Plane3 plane1(m_vertexs[face->getVertex(0)]->getPoint(), - m_vertexs[face->getVertex(1)]->getPoint(), - m_vertexs[face->getVertex(2)]->getPoint()); - - if (BOP_orientation(plane1,face->getPlane()) < 0) { - cout << "Test Plane " << face << " v1: "; - cout << m_vertexs[face->getVertex(0)]->getPoint() << " v2: "; - cout << m_vertexs[face->getVertex(1)]->getPoint() << " v3: "; - cout << m_vertexs[face->getVertex(2)]->getPoint() << " plane: "; - cout << face->getPlane() << endl; - cout << "Incorrect vertices order!!! plane1: " << plane1 << " ("; - cout << BOP_orientation(plane1,face->getPlane()) << ") " << " invert "; - cout << MT_Plane3(m_vertexs[face->getVertex(2)]->getPoint(), - m_vertexs[face->getVertex(1)]->getPoint(), - m_vertexs[face->getVertex(0)]->getPoint()) << endl; - if (BOP_collinear(m_vertexs[face->getVertex(0)]->getPoint(), - m_vertexs[face->getVertex(1)]->getPoint(), - m_vertexs[face->getVertex(2)]->getPoint())) { - cout << " COLLINEAR!!!" << endl; - } - else { - cout << endl; - } - } -} - -/** - * testEdges - */ -bool BOP_Mesh::testEdges(BOP_Faces *facesObj) -{ - for(unsigned int i=0;i<m_edges.size();i++) { - BOP_Edge *edge = m_edges[i]; - BOP_Indexs faces = edge->getFaces(); - unsigned int count = 0; - const BOP_IT_Indexs facesEnd = faces.end(); - for(BOP_IT_Indexs it = faces.begin();it!=facesEnd;it++) { - if ((m_faces[*it]->getTAG()!=BROKEN) && containsFace(facesObj,m_faces[*it])) - count++; - } - if ((count%2)!=0) { - return false; - } - } - - return true; -} - -/** - * updatePlanes - */ -void BOP_Mesh::updatePlanes() -{ - const BOP_IT_Faces facesEnd = m_faces.end(); - for(BOP_IT_Faces it = m_faces.begin();it!=facesEnd;it++) { - BOP_Face *face = *it; - MT_Plane3 plane(m_vertexs[face->getVertex(0)]->getPoint(), - m_vertexs[face->getVertex(1)]->getPoint(), - m_vertexs[face->getVertex(2)]->getPoint()); - face->setPlane(plane); - } -} - -#endif diff --git a/intern/boolop/intern/BOP_Mesh.h b/intern/boolop/intern/BOP_Mesh.h deleted file mode 100644 index 9c1b4ad04ea..00000000000 --- a/intern/boolop/intern/BOP_Mesh.h +++ /dev/null @@ -1,118 +0,0 @@ -/* - * - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file boolop/intern/BOP_Mesh.h - * \ingroup boolopintern - */ - - -#ifndef __BOP_MESH_H__ -#define __BOP_MESH_H__ - -#include "BOP_Vertex.h" -#include "BOP_Edge.h" -#include "BOP_Face.h" -#include "DNA_listBase.h" - -typedef std::vector<BOP_Vertex *> BOP_Vertexs; -typedef std::vector<BOP_Edge *> BOP_Edges; -typedef std::vector<BOP_Vertex *>::iterator BOP_IT_Vertexs; -typedef std::vector<BOP_Edge *>::iterator BOP_IT_Edges; - -#ifdef HASH -typedef struct EdgeEntry { - struct EdgeEntry *next, *pref; - BOP_Index v1, v2, index; -} EdgeEntry; -#endif - -class BOP_Mesh -{ -private: - BOP_Vertexs m_vertexs; - BOP_Edges m_edges; - BOP_Faces m_faces; -#ifdef HASH - ListBase *hash; - int hashsize; -#endif - - BOP_Index addEdge(BOP_Index v1, BOP_Index v2); - BOP_Edge *getEdge(BOP_Indexs edges, BOP_Index v2); - bool containsFace(BOP_Faces *faces, BOP_Face *face); - - bool testEdges(BOP_Faces *faces); - bool testFaces(BOP_Face *faceI, BOP_Face *faceJ); - bool testFace(BOP_Face *face); - -public: - BOP_Mesh(); - ~BOP_Mesh(); - - BOP_Index addVertex(MT_Point3 point); - BOP_Index addFace(BOP_Face *face); - BOP_Index addFace(BOP_Face3 *face); - BOP_Index addFace(BOP_Face4 *face); - BOP_Vertex* getVertex(BOP_Index v); - BOP_Face*getFace(BOP_Index v); - BOP_Edge* getEdge(BOP_Index v); - BOP_Edge* getEdge(BOP_Face * face, unsigned int edge); - BOP_Edge* getEdge(BOP_Face3 * face, unsigned int edge); - BOP_Edge* getEdge(BOP_Face4 * face, unsigned int edge); - BOP_Edge* getEdge(BOP_Index v1, BOP_Index v2); - bool getIndexEdge(BOP_Index v1, BOP_Index v2, BOP_Index &e); - BOP_Vertexs &getVertexs(); - BOP_Edges &getEdges(); - BOP_Faces &getFaces(); - BOP_Face* getFace(BOP_Index v1, BOP_Index v2, BOP_Index v3); - bool getIndexFace(BOP_Index v1, BOP_Index v2, BOP_Index v3, BOP_Index &f); - unsigned int getNumVertexs(); - unsigned int getNumEdges(); - unsigned int getNumFaces(); - unsigned int getNumVertexs(BOP_TAG tag); - unsigned int getNumFaces(BOP_TAG tag); - BOP_Index replaceVertexIndex(BOP_Index oldIndex, BOP_Index newIndex); -#ifdef HASH - void rehashVertex(BOP_Index oldIndex, BOP_Index newIndex, - BOP_Index otherIndex); -#endif - bool isClosedMesh(); - - // Debug functions - void print(); - void printFormat(); - void printFormat(BOP_Faces *faces); - void saveFormat(BOP_Faces *faces, char *filename); - void printFace(BOP_Face *face, int col = 0); - void testPlane(BOP_Face *face); - void testMesh(); - void updatePlanes(); -}; - -#endif diff --git a/intern/boolop/intern/BOP_Misc.h b/intern/boolop/intern/BOP_Misc.h deleted file mode 100644 index 4a808771df2..00000000000 --- a/intern/boolop/intern/BOP_Misc.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): Ken Hughes - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file boolop/intern/BOP_Misc.h - * \ingroup boolopintern - */ - - -/* - * This file contains various definitions used across the modules - */ - -/* - * define operator>> for faces, edges and vertices, and also add some - * debugging functions for displaying various internal data structures - */ - -// #define BOP_DEBUG - -#define HASH(x) ((x) >> 5) /* each "hash" covers 32 indices */ -// #define HASH_PRINTF_DEBUG /* uncomment to enable debug output */ - -/* - * temporary: control which method is used to merge final triangles and - * quads back together after an operation. If both methods are included, - * the "rt" debugging button on the Scene panel (F10) is used to control - * which is active. Setting it to 100 enables the original method, any - * other value enables the new method. - */ - -#define BOP_ORIG_MERGE /* include original merge code */ -#define BOP_NEW_MERGE /* include new merge code */ diff --git a/intern/boolop/intern/BOP_Segment.cpp b/intern/boolop/intern/BOP_Segment.cpp deleted file mode 100644 index 79e04380015..00000000000 --- a/intern/boolop/intern/BOP_Segment.cpp +++ /dev/null @@ -1,249 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file boolop/intern/BOP_Segment.cpp - * \ingroup boolopintern - */ - - -#include "BOP_Segment.h" - -#define UNDEFINED 0 - -/** - * Constructs a new segment. - */ -BOP_Segment::BOP_Segment(){ - m_cfg1 = UNDEFINED; - m_cfg2 = UNDEFINED; -} - -/** - * Returns the relative edge index between two relative vertex indices. - * @param v1 relative vertex index - * @param v2 relative vertex index - * @return relative edge index between two relative vertex indices, -1 otherwise - */ -int BOP_Segment::getEdgeBetween(unsigned int v1, unsigned int v2) -{ - if ((v1 == 1 && v2 == 2) || (v1 == 2 && v2 == 1)) return 1; - if ((v1 == 3 && v2 == 2) || (v1 == 2 && v2 == 3)) return 2; - if ((v1 == 1 && v2 == 3) || (v1 == 3 && v2 == 1)) return 3; - return -1; -} - -/** - * Returns if a relative vertex index is on a relative edge index. - * @param v relative vertex index - * @param e relative edge index - * @return true if the relative vertex index is on the relative edge index, - * false otherwise. - */ -bool BOP_Segment::isOnEdge(unsigned int v, unsigned int e) -{ - if (v == 1 && (e == 1 || e == 3)) return true; - if (v == 2 && (e == 1 || e == 2)) return true; - if (v == 3 && (e == 2 || e == 3)) return true; - return false; -} - -/** - * Inverts the segment, swapping ends data. - */ -void BOP_Segment::invert() -{ - BOP_Index aux = m_v1; - m_v1 = m_v2; - m_v2 = aux; - aux = m_cfg1; - m_cfg1 = m_cfg2; - m_cfg2 = aux; -} - -/** - * Sorts the segment according to ends configuration. - * The criterion to sort is ... - * - * UNDEFINED < VERTEX < EDGE < IN - * cfg1 > cfg2 - * - * so ... - * - * VERTEX(cfg1) => UNDEFINED(cfg2) || VERTEX(cfg2) - * EDGE(cfg1) => UNDEFINED(cfg2) || VERTEX(cfg2) || EDGE(cfg2) - * IN(cfg1) => UNDEFINED(cfg2) || VERTEX(cfg2) || EDGE(cfg2) || IN(cfg2) - */ -void BOP_Segment::sort() -{ - if (m_cfg1 < m_cfg2) invert(); -} - -/** - * Returns if the specified end segment configuration is IN. - * @return true if the specified end segment configuration is IN, false otherwise - */ -bool BOP_Segment::isIn(unsigned int cfg) -{ - return (cfg == 20); -} - -/** - * Returns if the specified end segment configuration is EDGE. - * @return true if the specified end segment configuration is EDGE, false otherwise - */ -bool BOP_Segment::isEdge(unsigned int cfg) -{ - return (cfg > 10) && (cfg < 20); -} - -/** - * Returns if the specified end segment configuration is VERTEX. - * @return true if the specified end segment configuration is VERTEX, false otherwise - */ -bool BOP_Segment::isVertex(unsigned int cfg) -{ - return (cfg!=UNDEFINED) && (cfg < 10); -} - -/** - * Returns if the specified end segment configuration is DEFINED (not UNDEFINED). - * @return true if the specified end segment configuration is DEFINED, false otherwise - */ -bool BOP_Segment::isDefined(unsigned int cfg) -{ - return (cfg != UNDEFINED); -} - -/** - * Returns if the specified end segment configuration is UNDEFINED. - * @return true if the specified end segment configuration is UNDEFINED, false otherwise - */ -bool BOP_Segment::isUndefined(unsigned int cfg) -{ - return (cfg == UNDEFINED); -} - -/** - * Returns the relative edge index from the specified end segment configuration. - * @return relative edge index from the specified end segment configuration - */ -unsigned int BOP_Segment::getEdge(unsigned int cfg) -{ - return cfg-10; -} - -/** - * Returns the relative vertex index from the specified end segment configuration. - * @return relative vertex index from the specified end segment configuration - */ -BOP_Index BOP_Segment::getVertex(unsigned int cfg) -{ - return cfg; -} - -/** - * Returns the end segment configuration for the specified relative edge index. - * @return end segment configuration for the specified relative edge index - */ -unsigned int BOP_Segment::createEdgeCfg(unsigned int edge) -{ - return 10+edge; -} - -/** - * Returns the end segment configuration for the specified relative vertex index. - * @return end segment configuration for the specified relative vertex index - */ -unsigned int BOP_Segment::createVertexCfg(BOP_Index vertex) -{ - return vertex; -} - -/** - * Returns the end segment IN configuration. - * @return end segment IN configuration - */ -unsigned int BOP_Segment::createInCfg() -{ - return 20; -} - -/** - * Returns the end segment UNDEFINED configuration. - * @return end segment UNDEFINED configuration - */ -unsigned int BOP_Segment::createUndefinedCfg() -{ - return UNDEFINED; -} - -/** - * Returns the inner segment configuration. - * @return inner segment configuration - */ -unsigned int BOP_Segment::getConfig() -{ - if (isUndefined(m_cfg1)) return m_cfg2; - else if (isUndefined(m_cfg2)) return m_cfg1; - else if (isVertex(m_cfg1)) { - // v1 is vertex - if (isVertex(m_cfg2)) { - // v2 is vertex - return createEdgeCfg(getEdgeBetween(getVertex(m_cfg1),getVertex(m_cfg2))); - } - else if (isEdge(m_cfg2)) { - // v2 is edge - if (isOnEdge(m_cfg1,getEdge(m_cfg2))) return m_cfg2; - else return createInCfg(); //IN - } - else return createInCfg(); //IN - } - else if (isEdge(m_cfg1)) { - // v1 is edge - if (isVertex(m_cfg2)) { - // v2 is vertex - if (isOnEdge(m_cfg2,getEdge(m_cfg1))) return m_cfg1; - else return createInCfg(); //IN - } - else if (isEdge(m_cfg2)) { - // v2 is edge - if (m_cfg1 == m_cfg2) return m_cfg1; - else return createInCfg(); // IN - } - else return createInCfg(); // IN - } - else return createInCfg(); // IN -} - -/** - * Implements operator << - */ -std::ostream &operator<<(std::ostream &stream, const BOP_Segment &c) -{ - std::cout << "m_v1: " << c.m_v1 << "(" << c.m_cfg1 << ") m_v2: " << c.m_v2 << "(" << c.m_cfg2 << ")"; - return stream; -} diff --git a/intern/boolop/intern/BOP_Segment.h b/intern/boolop/intern/BOP_Segment.h deleted file mode 100644 index 5a49ae844c4..00000000000 --- a/intern/boolop/intern/BOP_Segment.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file boolop/intern/BOP_Segment.h - * \ingroup boolopintern - */ - - -#ifndef __BOP_SEGMENT_H__ -#define __BOP_SEGMENT_H__ - -#include "BOP_Indexs.h" -#include <iostream> - -class BOP_Segment -{ -private: - int getEdgeBetween(unsigned int v1, unsigned int v2); - bool isOnEdge(unsigned int v, unsigned int e); - -public: - // Cfg : Configuration of the vertices - // Values: - // 20 IN, - // 1X Intersected edge X{1,2,3} of the face, - // 0X Coincident vertice X{1,2,3} of the face, - // 0 otherwise - unsigned int m_cfg1, m_cfg2; - BOP_Index m_v1, m_v2; // if cfgX >0, vX is the vertice index of the face - BOP_Segment(); - - static bool isIn(unsigned int cfg); - static bool isEdge(unsigned int cfg); - static bool isVertex(unsigned int cfg); - static bool isDefined(unsigned int cfg); - static bool isUndefined(unsigned int cfg); - static unsigned int getEdge(unsigned int cfg); - static BOP_Index getVertex(unsigned int cfg); - static unsigned int createEdgeCfg(unsigned int edge); - static unsigned int createVertexCfg(BOP_Index vertex); - static unsigned int createInCfg(); - static unsigned int createUndefinedCfg(); - void invert(); - void sort(); - unsigned int getConfig(); - - friend std::ostream &operator<<(std::ostream &stream, const BOP_Segment &c); -}; - -#endif diff --git a/intern/boolop/intern/BOP_Splitter.cpp b/intern/boolop/intern/BOP_Splitter.cpp deleted file mode 100644 index 0839b6af30b..00000000000 --- a/intern/boolop/intern/BOP_Splitter.cpp +++ /dev/null @@ -1,194 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file boolop/intern/BOP_Splitter.cpp - * \ingroup boolopintern - */ - - -#include "BOP_Splitter.h" -#include "BOP_Tag.h" - -#include <iostream> - -/** - * Returns the split point resulting from intersect a plane and a mesh face - * according to its specified relative edge. - * @param plane split plane - * @param m mesh - * @param f face - * @param e relative edge index - * @return intersection point - */ -MT_Point3 BOP_splitEdge(MT_Plane3 plane, BOP_Mesh *m, BOP_Face *f, unsigned int e) -{ - int v1 = -1, v2 = -1; - - switch(e) { - case 1: - v1 = f->getVertex(0); - v2 = f->getVertex(1); - break; - case 2: - v1 = f->getVertex(1); - v2 = f->getVertex(2); - break; - case 3: - v1 = f->getVertex(2); - v2 = f->getVertex(0); - break; - default: - // wrong relative edge index! - break; - } - - MT_Point3 p1 = m->getVertex(v1)->getPoint(); - MT_Point3 p2 = m->getVertex(v2)->getPoint(); - return BOP_intersectPlane(plane,p1,p2); -} - -/** - * Returns the segment resulting from intersect a plane and a mesh face. - * @param plane split plane - * @param m mesh - * @param f face - * @return segment if there is intersection, NULL otherwise - */ -BOP_Segment BOP_splitFace(MT_Plane3 plane, BOP_Mesh *m, BOP_Face *f) -{ - BOP_Vertex *v1 = m->getVertex(f->getVertex(0)); - BOP_Vertex *v2 = m->getVertex(f->getVertex(1)); - BOP_Vertex *v3 = m->getVertex(f->getVertex(2)); - - // Classify face vertices - BOP_TAG tag1 = BOP_createTAG(BOP_classify(v1->getPoint(),plane)); - BOP_TAG tag2 = BOP_createTAG(BOP_classify(v2->getPoint(),plane)); - BOP_TAG tag3 = BOP_createTAG(BOP_classify(v3->getPoint(),plane)); - - // Classify face according to its vertices classification - BOP_TAG tag = BOP_createTAG(tag1,tag2,tag3); - - BOP_Segment s; - - switch(tag) { - case IN_IN_IN : - case OUT_OUT_OUT : - case ON_ON_ON : - s.m_cfg1 = s.m_cfg2 = BOP_Segment::createUndefinedCfg(); - break; - - case ON_OUT_OUT : - case ON_IN_IN : - s.m_v1 = f->getVertex(0); - s.m_cfg1 = BOP_Segment::createVertexCfg(1); - s.m_cfg2 = BOP_Segment::createUndefinedCfg(); - break; - - case OUT_ON_OUT : - case IN_ON_IN : - s.m_v1 = f->getVertex(1); - s.m_cfg1 = BOP_Segment::createVertexCfg(2); - s.m_cfg2 = BOP_Segment::createUndefinedCfg(); - break; - - case OUT_OUT_ON : - case IN_IN_ON : - s.m_v1 = f->getVertex(2); - s.m_cfg1 = BOP_Segment::createVertexCfg(3); - s.m_cfg2 = BOP_Segment::createUndefinedCfg(); - break; - - case ON_ON_IN : - case ON_ON_OUT : - s.m_v1 = f->getVertex(0); - s.m_v2 = f->getVertex(1); - s.m_cfg1 = BOP_Segment::createVertexCfg(1); - s.m_cfg2 = BOP_Segment::createVertexCfg(2); - break; - - case ON_OUT_ON : - case ON_IN_ON : - s.m_v1 = f->getVertex(0); - s.m_v2 = f->getVertex(2); - s.m_cfg1 = BOP_Segment::createVertexCfg(1); - s.m_cfg2 = BOP_Segment::createVertexCfg(3); - break; - - case OUT_ON_ON : - case IN_ON_ON : - s.m_v1 = f->getVertex(1); - s.m_v2 = f->getVertex(2); - s.m_cfg1 = BOP_Segment::createVertexCfg(2); - s.m_cfg2 = BOP_Segment::createVertexCfg(3); - break; - - case IN_OUT_ON : - case OUT_IN_ON : - s.m_v2 = f->getVertex(2); - s.m_cfg1 = BOP_Segment::createEdgeCfg(1); - s.m_cfg2 = BOP_Segment::createVertexCfg(3); - break; - - case IN_ON_OUT : - case OUT_ON_IN : - s.m_v1 = f->getVertex(1); - s.m_cfg1 = BOP_Segment::createVertexCfg(2); - s.m_cfg2 = BOP_Segment::createEdgeCfg(3); - break; - - case ON_IN_OUT : - case ON_OUT_IN : - s.m_v1 = f->getVertex(0); - s.m_cfg1 = BOP_Segment::createVertexCfg(1); - s.m_cfg2 = BOP_Segment::createEdgeCfg(2); - break; - - case OUT_IN_IN : - case IN_OUT_OUT : - s.m_cfg1 = BOP_Segment::createEdgeCfg(1); - s.m_cfg2 = BOP_Segment::createEdgeCfg(3); - break; - - case OUT_IN_OUT : - case IN_OUT_IN : - s.m_cfg1 = BOP_Segment::createEdgeCfg(1); - s.m_cfg2 = BOP_Segment::createEdgeCfg(2); - break; - - case OUT_OUT_IN : - case IN_IN_OUT : - s.m_cfg1 = BOP_Segment::createEdgeCfg(2); - s.m_cfg2 = BOP_Segment::createEdgeCfg(3); - break; - - default: - // wrong TAG! - break; - } - - return s; -} diff --git a/intern/boolop/intern/BOP_Splitter.h b/intern/boolop/intern/BOP_Splitter.h deleted file mode 100644 index 8d79b89aa91..00000000000 --- a/intern/boolop/intern/BOP_Splitter.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file boolop/intern/BOP_Splitter.h - * \ingroup boolopintern - */ - - -#ifndef __BOP_SPLITTER_H__ -#define __BOP_SPLITTER_H__ - -#include "BOP_MathUtils.h" -#include "BOP_Segment.h" -#include "BOP_Mesh.h" - -#include "MT_Plane3.h" -#include "MT_Point3.h" - -MT_Point3 BOP_splitEdge(MT_Plane3 plane, BOP_Mesh *mesh, BOP_Face *face, unsigned int edge); -BOP_Segment BOP_splitFace(MT_Plane3 plane, BOP_Mesh *mesh, BOP_Face *face); - -#endif diff --git a/intern/boolop/intern/BOP_Tag.cpp b/intern/boolop/intern/BOP_Tag.cpp deleted file mode 100644 index cdc04b67d4a..00000000000 --- a/intern/boolop/intern/BOP_Tag.cpp +++ /dev/null @@ -1,144 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file boolop/intern/BOP_Tag.cpp - * \ingroup boolopintern - */ - - -#include "BOP_Tag.h" - -/** - * Gets the tag description. - * @param t tag - * @param dest tag description - */ -void BOP_stringTAG(BOP_TAG t, char *dest) { - - switch(t){ - case IN_IN_IN: - sprintf(dest, "IN_IN_IN"); - break; - case IN_IN_ON: - sprintf(dest, "IN_IN_ON"); - break; - case IN_ON_IN: - sprintf(dest, "IN_ON_IN"); - break; - case IN_ON_ON: - sprintf(dest, "IN_ON_ON"); - break; - case ON_IN_IN: - sprintf(dest, "ON_IN_IN"); - break; - case ON_IN_ON: - sprintf(dest, "ON_IN_ON"); - break; - case ON_ON_IN: - sprintf(dest, "ON_ON_IN"); - break; - case ON_ON_ON: - sprintf(dest, "ON_ON_ON"); - break; - case OUT_OUT_OUT: - sprintf(dest, "OUT_OUT_OUT"); - break; - case OUT_OUT_ON: - sprintf(dest, "OUT_OUT_ON"); - break; - case OUT_ON_OUT: - sprintf(dest, "OUT_ON_OUT"); - break; - case OUT_ON_ON: - sprintf(dest, "OUT_ON_ON"); - break; - case ON_OUT_OUT: - sprintf(dest, "ON_OUT_OUT"); - break; - case ON_OUT_ON: - sprintf(dest, "ON_OUT_ON"); - break; - case ON_ON_OUT: - sprintf(dest, "ON_ON_OUT"); - break; - case OUT_OUT_IN: - sprintf(dest, "OUT_OUT_IN"); - break; - case OUT_IN_OUT: - sprintf(dest, "OUT_IN_OUT"); - break; - case OUT_IN_IN: - sprintf(dest, "OUT_IN_IN"); - break; - case IN_OUT_OUT: - sprintf(dest, "IN_OUT_OUT"); - break; - case IN_OUT_IN: - sprintf(dest, "IN_OUT_IN"); - break; - case IN_IN_OUT: - sprintf(dest, "IN_IN_OUT"); - break; - case OUT_ON_IN: - sprintf(dest, "OUT_ON_IN"); - break; - case OUT_IN_ON: - sprintf(dest, "OUT_IN_ON"); - break; - case IN_ON_OUT: - sprintf(dest, "IN_ON_OUT"); - break; - case IN_OUT_ON: - sprintf(dest, "IN_OUT_ON"); - break; - case ON_IN_OUT: - sprintf(dest, "ON_IN_OUT"); - break; - case ON_OUT_IN: - sprintf(dest, "ON_OUT_IN"); - break; - case UNCLASSIFIED: - sprintf(dest, "UNCLASSIFIED"); - break; - case BROKEN: - sprintf(dest, "BROKEN"); - break; - case PHANTOM: - sprintf(dest, "PHANTOM"); - break; - case OVERLAPPED: - sprintf(dest, "OVERLAPPED"); - break; - case INOUT: - sprintf(dest, "INOUT"); - break; - default: - sprintf(dest, "DESCONEGUT %d",t); - break; - } - -} diff --git a/intern/boolop/intern/BOP_Tag.h b/intern/boolop/intern/BOP_Tag.h deleted file mode 100644 index b7438275e90..00000000000 --- a/intern/boolop/intern/BOP_Tag.h +++ /dev/null @@ -1,147 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file boolop/intern/BOP_Tag.h - * \ingroup boolopintern - */ - - -#include <string.h> -#include <stdio.h> - -#ifndef __BOP_TAG_H__ -#define __BOP_TAG_H__ - -#define IN_TAG 0x02 // Below the plane -#define ON_TAG 0x00 // On the plane -#define OUT_TAG 0x01 // Above the plane -#define INOUT_TAG 0x0E // Above and below the plane -#define INON_TAG 0x12 // Below and on the plane -#define OUTON_TAG 0x11 // Above and on the plane -#define UNCLASSIFIED_TAG 0x0F // Expecting to be classified - -#define PHANTOM_TAG 0x0C // Phantom face: verts form collinear triangle -#define OVERLAPPED_TAG 0x0D // Overlapped face -#define BROKEN_TAG 0x0B // Splitted and unused ... - -#define ON_ON_IN_TAG IN_TAG -#define ON_IN_ON_TAG IN_TAG << 2 -#define IN_ON_ON_TAG IN_TAG << 4 - -#define ON_ON_OUT_TAG OUT_TAG -#define ON_OUT_ON_TAG OUT_TAG << 2 -#define OUT_ON_ON_TAG OUT_TAG << 4 - -#define ON_ON_ON_TAG ON_TAG -#define IN_IN_IN_TAG IN_ON_ON_TAG | ON_IN_ON_TAG | ON_ON_IN_TAG -#define OUT_OUT_OUT_TAG OUT_ON_ON_TAG | ON_OUT_ON_TAG | ON_ON_OUT_TAG - -#define IN_IN_ON_TAG IN_ON_ON_TAG | ON_IN_ON_TAG -#define IN_ON_IN_TAG IN_ON_ON_TAG | ON_ON_IN_TAG -#define ON_IN_IN_TAG ON_IN_ON_TAG | ON_ON_IN_TAG - -#define OUT_OUT_ON_TAG OUT_ON_ON_TAG | ON_OUT_ON_TAG -#define OUT_ON_OUT_TAG OUT_ON_ON_TAG | ON_ON_OUT_TAG -#define ON_OUT_OUT_TAG ON_OUT_ON_TAG | ON_ON_OUT_TAG - -#define IN_OUT_OUT_TAG IN_ON_ON_TAG | ON_OUT_OUT_TAG -#define OUT_IN_OUT_TAG ON_IN_ON_TAG | OUT_ON_OUT_TAG -#define OUT_OUT_IN_TAG ON_ON_IN_TAG | OUT_OUT_ON_TAG - -#define OUT_IN_IN_TAG ON_IN_IN_TAG | OUT_ON_ON_TAG -#define IN_OUT_IN_TAG IN_ON_IN_TAG | ON_OUT_ON_TAG -#define IN_IN_OUT_TAG IN_IN_ON_TAG | ON_ON_OUT_TAG - -#define IN_ON_OUT_TAG IN_ON_ON_TAG | ON_ON_OUT_TAG -#define IN_OUT_ON_TAG IN_ON_ON_TAG | ON_OUT_ON_TAG -#define ON_IN_OUT_TAG ON_IN_ON_TAG | ON_ON_OUT_TAG -#define ON_OUT_IN_TAG ON_ON_IN_TAG | ON_OUT_ON_TAG -#define OUT_IN_ON_TAG ON_IN_ON_TAG | OUT_ON_ON_TAG -#define OUT_ON_IN_TAG ON_ON_IN_TAG | OUT_ON_ON_TAG - -typedef enum BOP_TAGEnum { - IN = IN_TAG, - ON = ON_TAG, - OUT = OUT_TAG, - INOUT = INOUT_TAG, - INON = INON_TAG, - OUTON = OUTON_TAG, - UNCLASSIFIED = UNCLASSIFIED_TAG, - PHANTOM = PHANTOM_TAG, - OVERLAPPED = OVERLAPPED_TAG, - BROKEN = BROKEN_TAG, - IN_ON_ON = IN_ON_ON_TAG, - ON_IN_ON = ON_IN_ON_TAG, - ON_ON_IN = ON_ON_IN_TAG, - OUT_ON_ON = OUT_ON_ON_TAG, - ON_OUT_ON = ON_OUT_ON_TAG, - ON_ON_OUT = ON_ON_OUT_TAG, - ON_ON_ON = ON_ON_ON_TAG, - IN_IN_IN = IN_IN_IN_TAG, - OUT_OUT_OUT = OUT_OUT_OUT_TAG, - IN_IN_ON = IN_IN_ON_TAG, - IN_ON_IN = IN_ON_IN_TAG, - ON_IN_IN = ON_IN_IN_TAG, - OUT_OUT_ON = OUT_OUT_ON_TAG, - OUT_ON_OUT = OUT_ON_OUT_TAG, - ON_OUT_OUT = ON_OUT_OUT_TAG, - IN_OUT_OUT = IN_OUT_OUT_TAG, - OUT_IN_OUT = OUT_IN_OUT_TAG, - OUT_OUT_IN = OUT_OUT_IN_TAG, - OUT_IN_IN = OUT_IN_IN_TAG, - IN_OUT_IN = IN_OUT_IN_TAG, - IN_IN_OUT = IN_IN_OUT_TAG, - IN_ON_OUT = IN_ON_OUT_TAG, - IN_OUT_ON = IN_OUT_ON_TAG, - ON_IN_OUT = ON_IN_OUT_TAG, - ON_OUT_IN = ON_OUT_IN_TAG, - OUT_IN_ON = OUT_IN_ON_TAG, - OUT_ON_IN = OUT_ON_IN_TAG } BOP_TAG; - -inline BOP_TAG BOP_createTAG(BOP_TAG tag1, BOP_TAG tag2, BOP_TAG tag3) -{ - return (BOP_TAG) (tag1 << 4 | tag2 << 2 | tag3); -} - -inline BOP_TAG BOP_createTAG(int i) -{ - return i < 0 ? IN : i > 0 ? OUT : ON; -} - -inline BOP_TAG BOP_addON(BOP_TAG tag) -{ - return (tag==IN?INON:(tag==OUT?OUTON:tag)); -} - -void BOP_stringTAG(BOP_TAG tag, char *dest); - -inline bool BOP_compTAG(BOP_TAG tag1, BOP_TAG tag2) -{ - return (tag1==tag2) || (BOP_addON(tag1) == BOP_addON(tag2)); -} - -#endif diff --git a/intern/boolop/intern/BOP_Triangulator.cpp b/intern/boolop/intern/BOP_Triangulator.cpp deleted file mode 100644 index 65f7dae1c0c..00000000000 --- a/intern/boolop/intern/BOP_Triangulator.cpp +++ /dev/null @@ -1,573 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file boolop/intern/BOP_Triangulator.cpp - * \ingroup boolopintern - */ - - -#include "BOP_Triangulator.h" -#include <iostream> - -void BOP_addFace(BOP_Mesh* mesh, BOP_Faces *faces, BOP_Face* face, BOP_TAG tag); -void BOP_splitQuad(BOP_Mesh* mesh, MT_Plane3 plane, BOP_Index v1, BOP_Index v2, BOP_Index v3, BOP_Index v4, - BOP_Face* triangles[], BOP_Index original); -BOP_Index BOP_getTriangleVertex(BOP_Mesh* mesh, BOP_Index v1, BOP_Index v2, BOP_Index v3, BOP_Index v4); -BOP_Index BOP_getNearestVertex(BOP_Mesh* mesh, BOP_Index u, BOP_Index v1, BOP_Index v2); -bool BOP_isInsideCircle(BOP_Mesh* mesh, BOP_Index v1, BOP_Index v2, BOP_Index v3, BOP_Index v4, BOP_Index v5); -bool BOP_isInsideCircle(BOP_Mesh* mesh, BOP_Index v1, BOP_Index v2, BOP_Index v3, BOP_Index w); -void BOP_triangulateC_split(BOP_Mesh* mesh, BOP_Faces* faces, BOP_Face* face, - BOP_Index v1, BOP_Index v2, BOP_Index v3, BOP_Index v4, BOP_Index v5); -void BOP_triangulateD_split(BOP_Mesh* mesh, BOP_Faces* faces, BOP_Face* face, - BOP_Index v1, BOP_Index v2, BOP_Index v3, BOP_Index v4, BOP_Index v5); - -/** - * Triangulates the face in two new faces by splitting one edge. - * - * * - * /|\ - * / | \ - * / | \ - * / | \ - * / | \ - * *-----x-----* - * - * @param mesh mesh that contains the faces, edges and vertices - * @param faces set of faces that contains face and will contains new faces - * @param face input face to be triangulate - * @param v vertex index that intersects the edge - * @param e relative edge index used to triangulate the face - */ - - -void BOP_triangulateA(BOP_Mesh *mesh, BOP_Faces *faces, BOP_Face * face, BOP_Index v, unsigned int e) -{ - BOP_Face *face1, *face2; - if (e == 1) { - face1 = new BOP_Face3(face->getVertex(0), v, face->getVertex(2), face->getPlane(), - face->getOriginalFace()); - face2 = new BOP_Face3(v, face->getVertex(1), face->getVertex(2), face->getPlane(), - face->getOriginalFace()); - } - else if (e == 2) { - face1 = new BOP_Face3(face->getVertex(0), face->getVertex(1), v, face->getPlane(), - face->getOriginalFace()); - face2 = new BOP_Face3(face->getVertex(0), v, face->getVertex(2), face->getPlane(), - face->getOriginalFace()); - } - else if (e == 3) { - face1 = new BOP_Face3(face->getVertex(0), face->getVertex(1), v, face->getPlane(), - face->getOriginalFace()); - face2 = new BOP_Face3(face->getVertex(1), face->getVertex(2), v, face->getPlane(), - face->getOriginalFace()); - } - else { - return; - } - - BOP_addFace(mesh, faces, face1, face->getTAG()); - BOP_addFace(mesh, faces, face2, face->getTAG()); - face1->setSplit(face->getSplit()); - face2->setSplit(face->getSplit()); - - face->setTAG(BROKEN); - face->freeBBox(); -} - -/** - * Triangulates the face in three new faces by one inner point. - * - * * - * / \ - * / \ - * / \ - * / x \ - * / \ - * *-----------* - * - * @param mesh mesh that contains the faces, edges and vertices - * @param faces set of faces that contains face and will contains new faces - * @param face input face to be triangulate - * @param v vertex index that lays inside face - */ -void BOP_triangulateB(BOP_Mesh* mesh, BOP_Faces* faces, BOP_Face* face, BOP_Index v) -{ - BOP_Face *face1 = new BOP_Face3(face->getVertex(0), face->getVertex(1), v, face->getPlane(), - face->getOriginalFace()); - BOP_Face *face2 = new BOP_Face3(face->getVertex(1), face->getVertex(2), v, face->getPlane(), - face->getOriginalFace()); - BOP_Face *face3 = new BOP_Face3(face->getVertex(2), face->getVertex(0), v, face->getPlane(), - face->getOriginalFace()); - - BOP_addFace(mesh,faces,face1,face->getTAG()); - BOP_addFace(mesh,faces,face2,face->getTAG()); - BOP_addFace(mesh,faces,face3,face->getTAG()); - face1->setSplit(face->getSplit()); - face2->setSplit(face->getSplit()); - face3->setSplit(face->getSplit()); - face->setTAG(BROKEN); - face->freeBBox(); -} - - -/** - * Triangulates the face in five new faces by two inner points. - * - * * - * / \ - * / \ - * / \ - * / x x \ - * / \ - * *-----------* - * - * @param mesh mesh that contains the faces, edges and vertices - * @param faces set of faces that contains face and will contains new faces - * @param face input face to be triangulate - * @param v1 first vertex index that lays inside face - * @param v2 second vertex index that lays inside face - */ -void BOP_triangulateC(BOP_Mesh* mesh, BOP_Faces* faces, BOP_Face* face, BOP_Index v1, BOP_Index v2) -{ - if (!BOP_isInsideCircle(mesh, face->getVertex(0), v1, v2, face->getVertex(1), face->getVertex(2))) { - BOP_triangulateC_split(mesh, faces, face, face->getVertex(0), face->getVertex(1), - face->getVertex(2), v1, v2); - } - else if (!BOP_isInsideCircle(mesh, face->getVertex(1), v1, v2, face->getVertex(0), face->getVertex(2))) { - BOP_triangulateC_split(mesh, faces, face, face->getVertex(1), face->getVertex(2), - face->getVertex(0), v1, v2); - } - else if (!BOP_isInsideCircle(mesh, face->getVertex(2), v1, v2, face->getVertex(0), face->getVertex(1))) { - BOP_triangulateC_split(mesh, faces, face, face->getVertex(2), face->getVertex(0), - face->getVertex(1), v1, v2); - } - else { - BOP_triangulateC_split(mesh, faces, face, face->getVertex(2), face->getVertex(0), - face->getVertex(1), v1, v2); - } -} - -/** - * Triangulates the face (v1,v2,v3) in five new faces by two inner points (v4,v5), where - * v1 v4 v5 defines the nice triangle and v4 v5 v2 v3 defines the quad to be tessellated. - * @param mesh mesh that contains the faces, edges and vertices - * @param faces set of faces that contains face and will contains new faces - * @param face input face to be triangulate - * @param v1 first vertex index that defines the original triangle - * @param v2 second vertex index that defines the original triangle - * @param v3 third vertex index that defines the original triangle - * @param v4 first vertex index that lays inside face - * @param v5 second vertex index that lays inside face - */ -void BOP_triangulateC_split(BOP_Mesh* mesh, BOP_Faces* faces, BOP_Face* face, - BOP_Index v1, BOP_Index v2, BOP_Index v3, BOP_Index v4, BOP_Index v5) -{ - BOP_Index v = BOP_getTriangleVertex(mesh, v1, v2, v4, v5); - BOP_Index w = (v == v4 ? v5 : v4); - BOP_Face *face1 = new BOP_Face3(v1, v, w, face->getPlane(), face->getOriginalFace()); - BOP_Face *face2 = new BOP_Face3(v1, v2, v, face->getPlane(), face->getOriginalFace()); - BOP_Face *face3 = new BOP_Face3(v1, w, v3, face->getPlane(), face->getOriginalFace()); - - // v1 v w defines the nice triangle in the correct order - // v1 v2 v defines one lateral triangle in the correct order - // v1 w v3 defines the other lateral triangle in the correct order - // w v v2 v3 defines the quad in the correct order - - BOP_addFace(mesh, faces, face1, face->getTAG()); - BOP_addFace(mesh, faces, face2, face->getTAG()); - BOP_addFace(mesh, faces, face3, face->getTAG()); - - face1->setSplit(face->getSplit()); - face2->setSplit(face->getSplit()); - face3->setSplit(face->getSplit()); - - BOP_Face *faces45[2]; - - BOP_splitQuad(mesh, face->getPlane(), v2, v3, w, v, faces45, face->getOriginalFace()); - BOP_addFace(mesh, faces, faces45[0], face->getTAG()); - BOP_addFace(mesh, faces, faces45[1], face->getTAG()); - faces45[0]->setSplit(face->getSplit()); - faces45[1]->setSplit(face->getSplit()); - - face->setTAG(BROKEN); - face->freeBBox(); -} - - -/** - * Triangulates the face in three new faces by splitting twice an edge. - * - * * - * / \ - * / \ - * / \ - * / \ - * / \ - * *---x---x---* - * - * @param mesh mesh that contains the faces, edges and vertices - * @param faces set of faces that contains face and will contains new faces - * @param face input face to be triangulate - * @param v1 first vertex index that intersects the edge - * @param v2 second vertex index that intersects the edge - * @param e relative edge index used to triangulate the face - */ -void BOP_triangulateD(BOP_Mesh* mesh, BOP_Faces* faces, BOP_Face* face, BOP_Index v1, - BOP_Index v2, unsigned int e) -{ - if (e == 1) { - BOP_triangulateD_split(mesh, faces, face, face->getVertex(0), face->getVertex(1), - face->getVertex(2), v1, v2); - } - else if (e == 2) { - BOP_triangulateD_split(mesh, faces, face, face->getVertex(1), face->getVertex(2), - face->getVertex(0), v1, v2); - } - else if (e == 3) { - BOP_triangulateD_split(mesh, faces, face, face->getVertex(2), face->getVertex(0), - face->getVertex(1), v1, v2); - } -} - -/** - * Triangulates the face (v1,v2,v3) in three new faces by splitting twice an edge. - * @param mesh mesh that contains the faces, edges and vertices - * @param faces set of faces that contains face and will contains new faces - * @param face input face to be triangulate - * @param v1 first vertex index that defines the original triangle - * @param v2 second vertex index that defines the original triangle - * @param v3 third vertex index that defines the original triangle - * @param v4 first vertex index that lays on the edge - * @param v5 second vertex index that lays on the edge - */ -void BOP_triangulateD_split(BOP_Mesh* mesh, BOP_Faces* faces, BOP_Face* face, - BOP_Index v1, BOP_Index v2, BOP_Index v3, BOP_Index v4, BOP_Index v5) -{ - BOP_Index v = BOP_getNearestVertex(mesh, v1, v4, v5); - BOP_Index w = (v == v4 ? v5 : v4); - BOP_Face *face1 = new BOP_Face3(v1, v, v3, face->getPlane(), face->getOriginalFace()); - BOP_Face *face2 = new BOP_Face3(v, w, v3, face->getPlane(), face->getOriginalFace()); - BOP_Face *face3 = new BOP_Face3(w, v2, v3, face->getPlane(), face->getOriginalFace()); - - BOP_addFace(mesh, faces, face1, face->getTAG()); - BOP_addFace(mesh, faces, face2, face->getTAG()); - BOP_addFace(mesh, faces, face3, face->getTAG()); - face1->setSplit(face->getSplit()); - face2->setSplit(face->getSplit()); - face3->setSplit(face->getSplit()); - - face->setTAG(BROKEN); - face->freeBBox(); -} - - -/** - * Triangulates the face in three new faces by splitting two edges. - * - * * - * / \ - * / \ - * x x - * / \ - * / \ - * *-----------* - * - * @param mesh mesh that contains the faces, edges and vertices - * @param faces set of faces that contains face and will contains new faces - * @param face input face to be triangulate - * @param v1 vertex index that intersects the first edge - * @param v1 vertex index that intersects the second edge - * @param e1 first relative edge index used to triangulate the face - * @param e2 second relative edge index used to triangulate the face - */ -void BOP_triangulateE(BOP_Mesh* mesh, BOP_Faces* faces, BOP_Face* face, - BOP_Index v1, BOP_Index v2, unsigned int e1, unsigned int e2) -{ - // Sort the edges to reduce the cases - if (e1 > e2) { - unsigned int aux = e1; - e1 = e2; - e2 = aux; - aux = v1; - v1 = v2; - v2 = aux; - } - // e1 < e2! - BOP_Face *face1; - BOP_Face *faces23[2]; - if (e1 == 1 && e2 == 2) { - // the vertex is 2 - face1 = new BOP_Face3(face->getVertex(1), v2, v1, face->getPlane(), - face->getOriginalFace()); - BOP_splitQuad(mesh, face->getPlane(), face->getVertex(2), face->getVertex(0), v1, v2, - faces23, face->getOriginalFace()); - } - else if (e1 == 1 && e2 == 3) { - // the vertex is 1 - face1 = new BOP_Face3(face->getVertex(0), v1, v2, face->getPlane(), - face->getOriginalFace()); - BOP_splitQuad(mesh, face->getPlane(), face->getVertex(1), face->getVertex(2), v2, v1, - faces23, face->getOriginalFace()); - } - else if (e1 == 2 && e2 == 3) { - // the vertex is 3 - face1 = new BOP_Face3(face->getVertex(2), v2, v1, face->getPlane(), - face->getOriginalFace()); - BOP_splitQuad(mesh, face->getPlane(), face->getVertex(0), face->getVertex(1), v1, v2, - faces23, face->getOriginalFace()); - } - else { - return; - } - - BOP_addFace(mesh, faces, face1, face->getTAG()); - BOP_addFace(mesh, faces, faces23[0], face->getTAG()); - BOP_addFace(mesh, faces, faces23[1], face->getTAG()); - face1->setSplit(face->getSplit()); - faces23[0]->setSplit(face->getSplit()); - faces23[1]->setSplit(face->getSplit()); - face->setTAG(BROKEN); - face->freeBBox(); -} - -/** - * Triangulates the face in four new faces by one edge and one inner point. - * - * * - * / \ - * / \ - * x x \ - * / \ - * / \ - * *-----------* - * - * @param mesh mesh that contains the faces, edges and vertices - * @param faces set of faces that contains face and will contains new faces - * @param face input face to be triangulate - * @param v1 vertex index that lays inside face - * @param v2 vertex index that intersects the edge - * @param e relative edge index used to triangulate the face - */ -void BOP_triangulateF(BOP_Mesh* mesh, BOP_Faces* faces, BOP_Face* face, - BOP_Index v1, BOP_Index v2, unsigned int e) -{ - BOP_Face *faces12[2]; - BOP_Face *faces34[2]; - if (e == 1) { - BOP_splitQuad(mesh, face->getPlane(), face->getVertex(2), face->getVertex(0), v2, v1, - faces12, face->getOriginalFace()); - BOP_splitQuad(mesh, face->getPlane(), face->getVertex(1), face->getVertex(2), v1, v2, - faces34, face->getOriginalFace()); - } - else if (e == 2) { - BOP_splitQuad(mesh, face->getPlane(), face->getVertex(0), face->getVertex(1), v2, v1, - faces12, face->getOriginalFace()); - BOP_splitQuad(mesh, face->getPlane(), face->getVertex(2), face->getVertex(0), v1, v2, - faces34, face->getOriginalFace()); - } - else if (e==3) { - BOP_splitQuad(mesh, face->getPlane(), face->getVertex(1), face->getVertex(2), v2, v1, - faces12, face->getOriginalFace()); - BOP_splitQuad(mesh, face->getPlane(), face->getVertex(0), face->getVertex(1), v1, v2, - faces34, face->getOriginalFace()); - } - else { - return; - } - - BOP_addFace(mesh, faces, faces12[0], face->getTAG()); - BOP_addFace(mesh, faces, faces12[1], face->getTAG()); - BOP_addFace(mesh, faces, faces34[0], face->getTAG()); - BOP_addFace(mesh, faces, faces34[1], face->getTAG()); - faces12[0]->setSplit(face->getSplit()); - faces12[1]->setSplit(face->getSplit()); - faces34[0]->setSplit(face->getSplit()); - faces34[1]->setSplit(face->getSplit()); - - face->setTAG(BROKEN); - face->freeBBox(); -} - -/** - * Adds the new face into the faces set and the mesh and sets it a new tag. - * @param mesh mesh that contains the faces, edges and vertices - * @param faces set of faces that contains oldFace - * @param face input face to be added - * @param tag tag of the new face - */ -void BOP_addFace(BOP_Mesh* mesh, BOP_Faces* faces, BOP_Face* face, BOP_TAG tag) -{ - BOP_Index av1 = face->getVertex(0); - BOP_Index av2 = face->getVertex(1); - BOP_Index av3 = face->getVertex(2); - - /* - * Before adding a new face to the face list, be sure it's not - * already there. Duplicate faces have been found to cause at - * least two instances of infinite loops. Also, some faces are - * created which have the same vertex twice. Don't add these either. - * - * When someone has more time to look into this issue, it's possible - * this code may be removed again. - */ - if( av1==av2 || av2==av3 || av3==av1 ) return; - - for(unsigned int idxFace=0;idxFace<faces->size();idxFace++) { - BOP_Face *faceA = (*faces)[idxFace]; - BOP_Index bv1 = faceA->getVertex(0); - BOP_Index bv2 = faceA->getVertex(1); - BOP_Index bv3 = faceA->getVertex(2); - - if( ( av1==bv1 && av2==bv2 && av3==bv3 ) || - ( av1==bv1 && av2==bv3 && av3==bv2 ) || - ( av1==bv2 && av2==bv1 && av3==bv3 ) || - ( av1==bv2 && av2==bv3 && av3==bv1 ) || - ( av1==bv3 && av2==bv2 && av3==bv1 ) || - ( av1==bv3 && av2==bv1 && av3==bv3 ) ) - return; - } - - face->setTAG(tag); - faces->push_back(face); - mesh->addFace(face); -} - -/** - * Computes the best quad triangulation. - * @param mesh mesh that contains the faces, edges and vertices - * @param plane plane used to create the news faces - * @param v1 first vertex index - * @param v2 second vertex index - * @param v3 third vertex index - * @param v4 fourth vertex index - * @param triangles array of faces where the new two faces will be saved - * @param original face index to the new faces - */ -void BOP_splitQuad(BOP_Mesh* mesh, MT_Plane3 plane, BOP_Index v1, BOP_Index v2, - BOP_Index v3, BOP_Index v4, BOP_Face* triangles[], BOP_Index original) -{ - MT_Point3 p1 = mesh->getVertex(v1)->getPoint(); - MT_Point3 p2 = mesh->getVertex(v2)->getPoint(); - MT_Point3 p3 = mesh->getVertex(v3)->getPoint(); - MT_Point3 p4 = mesh->getVertex(v4)->getPoint(); - - int res = BOP_concave(p1,p2,p3,p4); - - if (res==0) { - MT_Plane3 plane1(p1, p2, p3); - MT_Plane3 plane2(p1, p3, p4); - - if (BOP_isInsideCircle(mesh, v1, v2, v4, v3) && - BOP_orientation(plane1, plane) && - BOP_orientation(plane2, plane)) { - triangles[0] = new BOP_Face3(v1, v2, v3, plane, original); - triangles[1] = new BOP_Face3(v1, v3, v4, plane, original); - } - else { - triangles[0] = new BOP_Face3(v1, v2, v4, plane, original); - triangles[1] = new BOP_Face3(v2, v3, v4, plane, original); - } - } - else if (res==-1) { - triangles[0] = new BOP_Face3(v1, v2, v4, plane, original); - triangles[1] = new BOP_Face3(v2, v3, v4, plane, original); - } - else { - triangles[0] = new BOP_Face3(v1, v2, v3, plane, original); - triangles[1] = new BOP_Face3(v1, v3, v4, plane, original); - } -} - -/** - * Returns the vertex (v3 or v4) that splits the quad (v1,v2,v3,v4) in the best pair of triangles. - * @param mesh mesh that contains the faces, edges and vertices - * @param v1 first vertex index - * @param v2 second vertex index - * @param v3 third vertex index - * @param v4 fourth vertex index - * @return v3 if the best split triangles are (v1,v2,v3) and (v1,v3,v4), v4 otherwise - */ -BOP_Index BOP_getTriangleVertex(BOP_Mesh* mesh, BOP_Index v1, BOP_Index v2, BOP_Index v3, BOP_Index v4) -{ - if (BOP_isInsideCircle(mesh, v1, v2, v4, v3)) { - return v3; - } - return v4; -} - -/** - * Returns which of vertex v1 or v2 is nearest to u. - * @param mesh mesh that contains the faces, edges and vertices - * @param u reference vertex index - * @param v1 first vertex index - * @param v2 second vertex index - * @return the nearest vertex index - */ -BOP_Index BOP_getNearestVertex(BOP_Mesh* mesh, BOP_Index u, BOP_Index v1, BOP_Index v2) -{ - MT_Point3 q = mesh->getVertex(u)->getPoint(); - MT_Point3 p1 = mesh->getVertex(v1)->getPoint(); - MT_Point3 p2 = mesh->getVertex(v2)->getPoint(); - if (BOP_comp(q.distance(p1), q.distance(p2)) > 0) return v2; - else return v1; -} - -/** - * Computes if vertexs v4 and v5 are not inside the circle defined by v1,v2,v3 (seems to be a nice triangle) - * @param mesh mesh that contains the faces, edges and vertices - * @param v1 first vertex index - * @param v2 second vertex index - * @param v3 third vertex index - * @param v4 fourth vertex index - * @param v5 five vertex index - * @return if v1,v2,v3 defines a nice triangle against v4,v5 - */ -bool BOP_isInsideCircle(BOP_Mesh* mesh, BOP_Index v1, BOP_Index v2, BOP_Index v3, BOP_Index v4, BOP_Index v5) -{ - return BOP_isInsideCircle(mesh->getVertex(v1)->getPoint(), - mesh->getVertex(v2)->getPoint(), - mesh->getVertex(v3)->getPoint(), - mesh->getVertex(v4)->getPoint(), - mesh->getVertex(v5)->getPoint()); -} - -/** - * Computes if vertex w is not inside the circle defined by v1,v2,v3 (seems to be a nice triangle) - * @param mesh mesh that contains the faces, edges and vertices - * @param v1 first vertex index - * @param v2 second vertex index - * @param v3 third vertex index - * @param w fourth vertex index - * @return if v1,v2,v3 defines a nice triangle against w - */ -bool BOP_isInsideCircle(BOP_Mesh* mesh, BOP_Index v1, BOP_Index v2, BOP_Index v3, BOP_Index w) -{ - return BOP_isInsideCircle(mesh->getVertex(v1)->getPoint(), - mesh->getVertex(v2)->getPoint(), - mesh->getVertex(v3)->getPoint(), - mesh->getVertex(w)->getPoint()); -} diff --git a/intern/boolop/intern/BOP_Triangulator.h b/intern/boolop/intern/BOP_Triangulator.h deleted file mode 100644 index 55dd51d09c3..00000000000 --- a/intern/boolop/intern/BOP_Triangulator.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file boolop/intern/BOP_Triangulator.h - * \ingroup boolopintern - */ - - -#ifndef __BOP_TRIANGULATOR_H__ -#define __BOP_TRIANGULATOR_H__ - -#include "BOP_MathUtils.h" -#include "BOP_Mesh.h" - -void BOP_triangulateA(BOP_Mesh *mesh, BOP_Faces *faces, BOP_Face * face, BOP_Index v, unsigned int e); -void BOP_triangulateB(BOP_Mesh * mesh, BOP_Faces *faces, BOP_Face * face, BOP_Index v); -void BOP_triangulateC(BOP_Mesh * mesh, BOP_Faces *faces, BOP_Face * face, BOP_Index v1, BOP_Index v2); -void BOP_triangulateD(BOP_Mesh * mesh, BOP_Faces *faces, BOP_Face * face, BOP_Index v1, BOP_Index v2, unsigned int e); -void BOP_triangulateE(BOP_Mesh *mesh, BOP_Faces *faces, BOP_Face * face, BOP_Index v1, BOP_Index v2, unsigned int e1, unsigned int e2); -void BOP_triangulateF(BOP_Mesh *mesh, BOP_Faces *faces, BOP_Face * face, BOP_Index v1, BOP_Index v2, unsigned int e); - -#endif diff --git a/intern/boolop/intern/BOP_Vertex.cpp b/intern/boolop/intern/BOP_Vertex.cpp deleted file mode 100644 index a3377156f9d..00000000000 --- a/intern/boolop/intern/BOP_Vertex.cpp +++ /dev/null @@ -1,115 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file boolop/intern/BOP_Vertex.cpp - * \ingroup boolopintern - */ - - -#include "BOP_Vertex.h" - -/** - * Constructs a new vertex with the specified coordinates. - * @param x X-axis coordinate - * @param y Y-axis coordinate - * @param z Z-axis coordinate - */ -BOP_Vertex::BOP_Vertex(double x, double y, double z) -{ - m_point.setValue(x,y,z); - m_tag = UNCLASSIFIED; -} - -/** - * Constructs a new vertex with the specified point. - * @param p point XYZ - */ -BOP_Vertex::BOP_Vertex(MT_Point3 p) -{ - m_point = p; - m_tag = UNCLASSIFIED; -} - -/** - * Adds a new edge index to this vertex. - * @param i edge index - */ -void BOP_Vertex::addEdge(BOP_Index i) -{ - if (!containsEdge(i)) - m_edges.push_back(i); -} - -/** - * Removes an edge index from this vertex. - * @param i edge index - */ -void BOP_Vertex::removeEdge(BOP_Index i) -{ - for(BOP_IT_Indexs it = m_edges.begin();it!=m_edges.end();it++) { - if ((*it)==i) { - m_edges.erase(it); - return; - } - } -} - -/** - * Returns if this vertex contains the specified edge index. - * @param i edge index - * @return true if this vertex contains the specified edge index, false otherwise - */ -bool BOP_Vertex::containsEdge(BOP_Index i) -{ - int pos=0; - for(BOP_IT_Indexs it = m_edges.begin();it!=m_edges.end();pos++,it++) { - if ((*it)==i){ - return true; - } - } - - return false; -} - -#ifdef BOP_DEBUG -/** - * Implements operator <<. - */ -#include <iomanip> - -ostream &operator<<(ostream &stream, BOP_Vertex *v) -{ - char aux[20]; - BOP_stringTAG(v->m_tag,aux); - MT_Point3 point = v->getPoint(); - stream << setprecision(6) << showpoint << fixed; - stream << "Vertex[" << point[0] << "," << point[1] << ","; - stream << point[2] << "] (" << aux << ")"; - return stream; -} -#endif - diff --git a/intern/boolop/intern/BOP_Vertex.h b/intern/boolop/intern/BOP_Vertex.h deleted file mode 100644 index 1aae2207972..00000000000 --- a/intern/boolop/intern/BOP_Vertex.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file boolop/intern/BOP_Vertex.h - * \ingroup boolopintern - */ - - -#ifndef __BOP_VERTEX_H__ -#define __BOP_VERTEX_H__ - -#include "BOP_Tag.h" -#include "BOP_Indexs.h" -#include "MT_Point3.h" -#include "BOP_Misc.h" - -class BOP_Vertex -{ -private: - MT_Point3 m_point; - BOP_Indexs m_edges; - BOP_TAG m_tag; - - bool containsEdge(BOP_Index i); - -public: - BOP_Vertex(double x, double y, double z); - BOP_Vertex(MT_Point3 d); - void addEdge(BOP_Index i); - void removeEdge(BOP_Index i); - inline BOP_Index getEdge(unsigned int i) { return m_edges[i];}; - inline unsigned int getNumEdges() { return m_edges.size();}; - inline BOP_Indexs &getEdges() { return m_edges;}; - inline MT_Point3 getPoint() const { return m_point;}; - inline BOP_TAG getTAG() { return m_tag;}; - inline void setTAG(BOP_TAG t) { m_tag = t;}; -#ifdef BOP_DEBUG - friend ostream &operator<<(ostream &stream, BOP_Vertex *v); -#endif - -}; - -#endif diff --git a/intern/bsp/CMakeLists.txt b/intern/bsp/CMakeLists.txt index 6a337b99be9..e492c04423e 100644 --- a/intern/bsp/CMakeLists.txt +++ b/intern/bsp/CMakeLists.txt @@ -29,6 +29,7 @@ set(INC ../guardedalloc ../memutil ../moto/include + ../../extern/carve/include ) set(INC_SYS @@ -36,15 +37,34 @@ set(INC_SYS ) set(SRC + intern/BOP_CarveInterface.cpp intern/BSP_CSGMesh.cpp intern/BSP_MeshPrimitives.cpp intern/CSG_BooleanOps.cpp extern/CSG_BooleanOps.h + intern/BOP_Interface.h intern/BSP_CSGException.h intern/BSP_CSGMesh.h intern/BSP_CSGMesh_CFIterator.h intern/BSP_MeshPrimitives.h ) +if(WITH_BOOST) + if(NOT MSVC) + # Boost is setting as preferred collections library in the Carve code when using MSVC compiler + add_definitions( + -DHAVE_BOOST_UNORDERED_COLLECTIONS + ) + endif() + + add_definitions( + -DCARVE_SYSTEM_BOOST + ) + + list(APPEND INC + ${BOOST_INCLUDE_DIR} + ) +endif() + blender_add_lib(bf_intern_bsp "${SRC}" "${INC}" "${INC_SYS}") diff --git a/intern/bsp/SConscript b/intern/bsp/SConscript index 4927c33dc8a..d3f7cf1c6ec 100644 --- a/intern/bsp/SConscript +++ b/intern/bsp/SConscript @@ -3,7 +3,21 @@ Import ('env') sources = env.Glob('intern/*.cpp') -incs = 'intern ../container ../moto/include ../memutil ../guardedalloc' +incs = 'intern ../container ../moto/include ../memutil ../guardedalloc ../../extern/carve/include' -env.BlenderLib ('bf_intern_bsp', sources, Split(incs), [], libtype=['core','player'], priority=[200,100] ) +defs = [] + +if env['WITH_BF_BOOST']: + isMINGW = env['OURPLATFORM'] in ('win32-mingw', 'win64-mingw') + + if env['OURPLATFORM'] not in ('win32-vc', 'win64-vc') and not isMINGW: + # Boost is setting as preferred collections library in the Carve code when using MSVC compiler + defs.append('HAVE_BOOST_UNORDERED_COLLECTIONS') + + if not isMINGW: + defs.append('CARVE_SYSTEM_BOOST') + + incs += ' ' + env['BF_BOOST_INC'] + +env.BlenderLib ('bf_intern_bsp', sources, Split(incs), defs, libtype=['core','player'], priority=[200,100] ) diff --git a/intern/boolop/intern/BOP_CarveInterface.cpp b/intern/bsp/intern/BOP_CarveInterface.cpp index ff7244ea84b..255d885007c 100644 --- a/intern/boolop/intern/BOP_CarveInterface.cpp +++ b/intern/bsp/intern/BOP_CarveInterface.cpp @@ -26,12 +26,12 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file boolop/intern/BOP_CarveInterface.cpp - * \ingroup boolopintern +/** \file bsp/intern/BOP_CarveInterface.cpp + * \ingroup bsp */ -#include "../extern/BOP_Interface.h" -#include "../../bsp/intern/BSP_CSGMesh_CFIterator.h" +#include "BOP_Interface.h" +#include "BSP_CSGMesh_CFIterator.h" #include <carve/csg_triangulator.hpp> #include <carve/interpolator.hpp> @@ -547,13 +547,32 @@ static uint quadMerge(std::map<MeshSet<3>::vertex_t*, uint> *vertexToIndex_map, return 0; } -static bool Carve_checkDegeneratedFace(MeshSet<3>::face_t *face) +static bool Carve_checkDegeneratedFace(std::map<MeshSet<3>::vertex_t*, uint> *vertexToIndex_map, MeshSet<3>::face_t *face) { /* only tris and quads for now */ if (face->n_edges == 3) { + uint v1, v2, v3; + + v1 = vertexToIndex_map->find(face->edge->prev->vert)->second; + v2 = vertexToIndex_map->find(face->edge->vert)->second; + v3 = vertexToIndex_map->find(face->edge->next->vert)->second; + + if (v1 == v2 || v2 == v3 || v1 == v3) + return true; + return triangleArea(face->edge->prev->vert->v, face->edge->vert->v, face->edge->next->vert->v) < DBL_EPSILON; } else if (face->n_edges == 4) { + uint v1, v2, v3, v4; + + v1 = vertexToIndex_map->find(face->edge->prev->vert)->second; + v2 = vertexToIndex_map->find(face->edge->vert)->second; + v3 = vertexToIndex_map->find(face->edge->next->vert)->second; + v4 = vertexToIndex_map->find(face->edge->next->next->vert)->second; + + if (v1 == v2 || v1 == v3 || v1 == v4 || v2 == v3 || v2 == v4 || v3 == v4) + return true; + return triangleArea(face->edge->vert->v, face->edge->next->vert->v, face->edge->next->next->vert->v) + triangleArea(face->edge->prev->vert->v, face->edge->vert->v, face->edge->next->next->vert->v) < DBL_EPSILON; } @@ -595,8 +614,14 @@ static BSP_CSGMesh *Carve_exportMesh(MeshSet<3>* &poly, carve::interpolate::Face MeshSet<3>::face_iter face_iter = poly->faceBegin(); for (i = 0; face_iter != poly->faceEnd(); ++face_iter, ++i) { MeshSet<3>::face_t *f = *face_iter; + + if (Carve_checkDegeneratedFace(&vertexToIndex_map, f)) + continue; + ofaces[oface_num.getAttribute(f)].push_back(i); + MeshSet<3>::face_t::edge_iter_t edge_iter = f->begin(); + for (; edge_iter != f->end(); ++edge_iter) { int index = vertexToIndex_map[edge_iter->vert]; vi[index].push_back(i); @@ -659,36 +684,27 @@ static BSP_CSGMesh *Carve_exportMesh(MeshSet<3>* &poly, carve::interpolate::Face } } - bool degenerativeFace = false; - - if (!result) { - /* merged triangles are already checked for degenerative quad */ - degenerativeFace = Carve_checkDegeneratedFace(f); - } - - if (!degenerativeFace) { - // add all information except vertices to the output mesh - outputMesh->FaceSet().push_back(BSP_MFace()); - BSP_MFace& outFace = outputMesh->FaceSet().back(); - outFace.m_verts.clear(); - outFace.m_plane.setValue(f->plane.N.v); - outFace.m_orig_face = orig; - - // if we merged faces, use the list of common vertices; otherwise - // use the faces's vertices - if (result) { - // make quat using verts stored in result - outFace.m_verts.push_back(quadverts[0]); - outFace.m_verts.push_back(quadverts[1]); - outFace.m_verts.push_back(quadverts[2]); - outFace.m_verts.push_back(quadverts[3]); - } else { - MeshSet<3>::face_t::edge_iter_t edge_iter = f->begin(); - for (; edge_iter != f->end(); ++edge_iter) { - //int index = ofacevert_num.getAttribute(f, edge_iter.idx()); - int index = vertexToIndex_map[edge_iter->vert]; - outFace.m_verts.push_back( index ); - } + // add all information except vertices to the output mesh + outputMesh->FaceSet().push_back(BSP_MFace()); + BSP_MFace& outFace = outputMesh->FaceSet().back(); + outFace.m_verts.clear(); + outFace.m_plane.setValue(f->plane.N.v); + outFace.m_orig_face = orig; + + // if we merged faces, use the list of common vertices; otherwise + // use the faces's vertices + if (result) { + // make quat using verts stored in result + outFace.m_verts.push_back(quadverts[0]); + outFace.m_verts.push_back(quadverts[1]); + outFace.m_verts.push_back(quadverts[2]); + outFace.m_verts.push_back(quadverts[3]); + } else { + MeshSet<3>::face_t::edge_iter_t edge_iter = f->begin(); + for (; edge_iter != f->end(); ++edge_iter) { + //int index = ofacevert_num.getAttribute(f, edge_iter.idx()); + int index = vertexToIndex_map[edge_iter->vert]; + outFace.m_verts.push_back( index ); } } } diff --git a/intern/boolop/extern/BOP_Interface.h b/intern/bsp/intern/BOP_Interface.h index fbada7dcab5..c7402388a29 100644 --- a/intern/boolop/extern/BOP_Interface.h +++ b/intern/bsp/intern/BOP_Interface.h @@ -26,13 +26,13 @@ */ /** \file BOP_Interface.h - * \ingroup boolop + * \ingroup bsp */ #ifndef __BOP_INTERFACE_H__ #define __BOP_INTERFACE_H__ -#include "../../bsp/intern/BSP_CSGMesh.h" +#include "BSP_CSGMesh.h" typedef enum EnumBoolOpState {BOP_OK, BOP_NO_SOLID, BOP_ERROR} BoolOpState; typedef enum EnumBoolOpType {BOP_INTERSECTION=e_csg_intersection, BOP_UNION=e_csg_union, BOP_DIFFERENCE=e_csg_difference} BoolOpType; diff --git a/intern/bsp/intern/CSG_BooleanOps.cpp b/intern/bsp/intern/CSG_BooleanOps.cpp index df1374ef10b..4f71e7992a1 100644 --- a/intern/bsp/intern/CSG_BooleanOps.cpp +++ b/intern/bsp/intern/CSG_BooleanOps.cpp @@ -31,7 +31,6 @@ /** - * Implementation of external api for CSG part of BSP lib interface. */ @@ -39,7 +38,7 @@ #include "BSP_CSGMesh_CFIterator.h" #include "MEM_RefCountPtr.h" -#include "../../boolop/extern/BOP_Interface.h" +#include "BOP_Interface.h" #include <iostream> using namespace std; diff --git a/intern/bsp/test/BSP_GhostTest/BSP_GhostTest.dsp b/intern/bsp/test/BSP_GhostTest/BSP_GhostTest.dsp deleted file mode 100644 index 4474eaa5d90..00000000000 --- a/intern/bsp/test/BSP_GhostTest/BSP_GhostTest.dsp +++ /dev/null @@ -1,126 +0,0 @@ -# Microsoft Developer Studio Project File - Name="BSP_GhostTest" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=BSP_GhostTest - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "BSP_GhostTest.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "BSP_GhostTest.mak" CFG="BSP_GhostTest - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "BSP_GhostTest - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "BSP_GhostTest - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "BSP_GhostTest - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /G6 /MT /W3 /GX /O2 /Ob2 /I "../../extern/" /I "../../../../lib/windows/string/include" /I "../../../../lib/windows/ghost/include" /I "../../../../lib/windows/moto/include" /I "../../../../lib/windows/memutil/include" /I "../../../../lib/windows/container/include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x413 /d "NDEBUG"
-# ADD RSC /l 0x413 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 glu32.lib opengl32.lib kernel32.lib user32.lib gdi32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\..\lib\windows\glut-3.7\lib\\"
-
-!ELSEIF "$(CFG)" == "BSP_GhostTest - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../extern/" /I "../../../../lib/windows/string/include" /I "../../../../lib/windows/ghost/include" /I "../../../../lib/windows/moto/include" /I "../../../../lib/windows/memutil/include" /I "../../../../lib/windows/container/include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD BASE RSC /l 0x413 /d "_DEBUG"
-# ADD RSC /l 0x413 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 glu32.lib opengl32.lib user32.lib gdi32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\..\..\lib\windows\glut-3.7\lib\\"
-
-!ENDIF
-
-# Begin Target
-
-# Name "BSP_GhostTest - Win32 Release"
-# Name "BSP_GhostTest - Win32 Debug"
-# Begin Source File
-
-SOURCE=.\BSP_GhostTest3D.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\BSP_GhostTest3D.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\BSP_MeshDrawer.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\BSP_MeshDrawer.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\BSP_PlyLoader.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\BSP_PlyLoader.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\BSP_TMesh.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\main.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\ply.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\plyfile.c
-# End Source File
-# End Target
-# End Project
diff --git a/intern/bsp/test/BSP_GhostTest/BSP_GhostTest.dsw b/intern/bsp/test/BSP_GhostTest/BSP_GhostTest.dsw deleted file mode 100644 index 0d9ca3d2b08..00000000000 --- a/intern/bsp/test/BSP_GhostTest/BSP_GhostTest.dsw +++ /dev/null @@ -1,125 +0,0 @@ -Microsoft Developer Studio Workspace File, Format Version 6.00
-# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
-
-###############################################################################
-
-Project: "BSP_GhostTest"=.\BSP_GhostTest.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
- Begin Project Dependency
- Project_Dep_Name bsplib
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name ghost
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name string
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name MoTo
- End Project Dependency
-}}}
-
-###############################################################################
-
-Project: "MoTo"=..\..\..\moto\make\msvc_6_0\MoTo.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "bsplib"=..\..\make\msvc6_0\bsplib.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
- Begin Project Dependency
- Project_Dep_Name container
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name memutil
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name MoTo
- End Project Dependency
-}}}
-
-###############################################################################
-
-Project: "container"=..\..\..\container\make\msvc_6_0\container.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
- Begin Project Dependency
- Project_Dep_Name memutil
- End Project Dependency
-}}}
-
-###############################################################################
-
-Project: "ghost"=..\..\..\ghost\make\msvc\ghost.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "memutil"=..\..\..\memutil\make\msvc_60\memutil.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "string"=..\..\..\string\make\msvc_6_0\string.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Global:
-
-Package=<5>
-{{{
-}}}
-
-Package=<3>
-{{{
-}}}
-
-###############################################################################
-
diff --git a/intern/bsp/test/BSP_GhostTest/BSP_GhostTest3D.cpp b/intern/bsp/test/BSP_GhostTest/BSP_GhostTest3D.cpp deleted file mode 100644 index 46cde625cf2..00000000000 --- a/intern/bsp/test/BSP_GhostTest/BSP_GhostTest3D.cpp +++ /dev/null @@ -1,649 +0,0 @@ -/** - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** - -* Copyright (C) 2001 NaN Technologies B.V. -*/ -#if defined(WIN32) || defined(__APPLE__) -# ifdef WIN32 -# include <windows.h> -# include <GL/gl.h> -# include <GL/glu.h> -# else // WIN32 -# include <AGL/gl.h> -# endif // WIN32 -#else // defined(WIN32) || defined(__APPLE__) -# include <GL/gl.h> -# include <GL/glu.h> -#endif // defined(WIN32) || defined(__APPLE__) - - -#include "BSP_GhostTest3D.h" -#include "BSP_MeshDrawer.h" - -#include "GHOST_ISystem.h" -#include "GHOST_IWindow.h" - -#include "MT_Quaternion.h" -#include "MT_Transform.h" -#include "CSG_BooleanOps.h" - -#include <iostream> - - int -EmptyInterpFunc( - void *d1, - void * d2, - void *dnew, - float epsilon -){ - return 0; -} - - - -using namespace std; - - -BSP_GhostTestApp3D:: -BSP_GhostTestApp3D( -) : - m_window(NULL), - m_system(NULL), - m_finish_me_off(false), - m_current_object(0) -{ - //nothing to do; -} - - void -BSP_GhostTestApp3D:: -SetMesh( - MEM_SmartPtr<BSP_TMesh> mesh -){ - m_meshes.push_back(mesh); - - BSP_RotationSetting rotation_setting; - BSP_TranslationSetting translation_setting; - - rotation_setting.m_angle_x = MT_Scalar(0); - rotation_setting.m_angle_y = MT_Scalar(0); - rotation_setting.m_moving = false; - rotation_setting.x_old = 0; - rotation_setting.y_old = 0; - - translation_setting.m_t_x = MT_Scalar(0); - translation_setting.m_t_y = MT_Scalar(0); - translation_setting.m_t_z = MT_Scalar(0); - translation_setting.m_moving = false; - translation_setting.x_old = 0; - translation_setting.y_old = 0; - - m_rotation_settings.push_back(rotation_setting); - m_translation_settings.push_back(translation_setting); - m_render_modes.push_back(e_wireframe_shaded); - m_scale_settings.push_back(MT_Scalar(1)); - -} - - void -BSP_GhostTestApp3D:: -Swap( - int i -){ - - if (!m_rotation_settings[i].m_moving && !m_translation_settings[i].m_moving) { - swap(m_meshes[i],m_meshes.back()); - swap(m_rotation_settings[i],m_rotation_settings.back()); - swap(m_translation_settings[i],m_translation_settings.back()); - swap(m_scale_settings[i],m_scale_settings.back()); - swap(m_render_modes[i],m_render_modes.back()); - } -} - - - MT_Transform -BSP_GhostTestApp3D:: -GetTransform( - int i -){ - - MT_Quaternion q_ax(MT_Vector3(0,1,0),m_rotation_settings[i].m_angle_x); - MT_Quaternion q_ay(MT_Vector3(1,0,0),m_rotation_settings[i].m_angle_y); - - MT_Point3 tr( - m_translation_settings[i].m_t_x, - m_translation_settings[i].m_t_y, - m_translation_settings[i].m_t_z - ); - - - MT_Matrix3x3 rotx(q_ax); - MT_Matrix3x3 roty(q_ay); - - MT_Matrix3x3 rot = rotx * roty; - - MT_Transform trans(tr,rot); - - MT_Transform scalet; - scalet.setIdentity(); - scalet.scale(m_scale_settings[i],m_scale_settings[i],m_scale_settings[i]); - - return trans * scalet; -} - - void -BSP_GhostTestApp3D:: -Operate( - int type -){ - - CSG_VertexIteratorDescriptor * vA = VertexIt_Construct(m_meshes[0],GetTransform(0)); - CSG_FaceIteratorDescriptor * fA = FaceIt_Construct(m_meshes[0]); - - CSG_VertexIteratorDescriptor * vB = VertexIt_Construct(m_meshes[1],GetTransform(1)); - CSG_FaceIteratorDescriptor * fB = FaceIt_Construct(m_meshes[1]); - - // describe properties. - - CSG_MeshPropertyDescriptor props; - props.user_face_vertex_data_size = 0; - props.user_data_size = 0; - - CSG_BooleanOperation * op = CSG_NewBooleanFunction(); - props = CSG_DescibeOperands(op,props,props); - - CSG_PerformBooleanOperation( - op,CSG_OperationType(type), - *fA,*vA,*fB,*vB,EmptyInterpFunc - ); - - CSG_FaceIteratorDescriptor out_f; - CSG_OutputFaceDescriptor(op,&out_f); - - CSG_VertexIteratorDescriptor out_v; - CSG_OutputVertexDescriptor(op,&out_v); - - MEM_SmartPtr<BSP_TMesh> new_mesh (BuildMesh(props,out_f,out_v)); - - // free stuff - - CSG_FreeVertexDescriptor(&out_v); - CSG_FreeFaceDescriptor(&out_f); - CSG_FreeBooleanOperation(op); - - op = NULL; - SetMesh(new_mesh); -} - - - void -BSP_GhostTestApp3D:: -UpdateFrame( -) { - if (m_window) { - - GHOST_Rect v_rect; - m_window->getClientBounds(v_rect); - - glViewport(0,0,v_rect.getWidth(),v_rect.getHeight()); - - } -} - - -MT_Vector3 -BSP_GhostTestApp3D:: -UnProject( - const MT_Vector3 & vec -) { - - GLint viewport[4]; - GLdouble mvmatrix[16],projmatrix[16]; - - glGetIntegerv(GL_VIEWPORT,viewport); - glGetDoublev(GL_MODELVIEW_MATRIX,mvmatrix); - glGetDoublev(GL_PROJECTION_MATRIX,projmatrix); - - GLdouble realy = viewport[3] - vec.y() - 1; - GLdouble outx,outy,outz; - - gluUnProject(vec.x(),realy,vec.z(),mvmatrix,projmatrix,viewport,&outx,&outy,&outz); - - return MT_Vector3(outx,outy,outz); -} - - - bool -BSP_GhostTestApp3D:: -InitApp( -){ - - // create a system and window with opengl - // rendering context. - - GHOST_TSuccess success = GHOST_ISystem::createSystem(); - if (success == GHOST_kFailure) return false; - - m_system = GHOST_ISystem::getSystem(); - if (m_system == NULL) return false; - - m_system->addEventConsumer(this); - - m_window = m_system->createWindow( - "GHOST crud3D!", - 100,100,512,512,GHOST_kWindowStateNormal, - GHOST_kDrawingContextTypeOpenGL,false - ); - - if ( - m_window == NULL - ) { - m_system = NULL; - GHOST_ISystem::disposeSystem(); - return false; - } - - // make an opengl frustum for this wind - - MT_Vector3 min,max; - - min = m_meshes[0]->m_min; - max = m_meshes[0]->m_max; - InitOpenGl(min,max); - - return true; -} - - void -BSP_GhostTestApp3D:: -Run( -){ - if (m_system == NULL) { - return; - } - - while (!m_finish_me_off) { - m_system->processEvents(true); - m_system->dispatchEvents(); - }; -} - - bool -BSP_GhostTestApp3D:: -processEvent( - GHOST_IEvent* event -){ - - bool handled = false; - - switch(event->getType()) { - case GHOST_kEventWindowSize: - case GHOST_kEventWindowActivate: - UpdateFrame(); - case GHOST_kEventWindowUpdate: - DrawPolies(); - handled = true; - break; - case GHOST_kEventButtonDown: - { - int x,y; - m_system->getCursorPosition(x,y); - - - int wx,wy; - m_window->screenToClient(x,y,wx,wy); - - GHOST_TButtonMask button = - static_cast<GHOST_TEventButtonData *>(event->getData())->button; - - if (button == GHOST_kButtonMaskLeft) { - m_rotation_settings[m_current_object].m_moving = true; - m_rotation_settings[m_current_object].x_old = x; - m_rotation_settings[m_current_object].y_old = y; - } else - if (button == GHOST_kButtonMaskRight) { - m_translation_settings[m_current_object].m_moving = true; - m_translation_settings[m_current_object].x_old = x; - m_translation_settings[m_current_object].y_old = y; - } else - - m_window->invalidate(); - handled = true; - break; - - } - - case GHOST_kEventButtonUp: - { - - GHOST_TButtonMask button = - static_cast<GHOST_TEventButtonData *>(event->getData())->button; - - if (button == GHOST_kButtonMaskLeft) { - m_rotation_settings[m_current_object].m_moving = false; - m_rotation_settings[m_current_object].x_old = 0; - m_rotation_settings[m_current_object].y_old = 0; - - } else - if (button == GHOST_kButtonMaskRight) { - m_translation_settings[m_current_object].m_moving = false; - m_translation_settings[m_current_object].x_old; - m_translation_settings[m_current_object].y_old; - - } - m_window->invalidate(); - handled = true; - break; - - } - - case GHOST_kEventCursorMove: - { - int x,y; - m_system->getCursorPosition(x,y); - int wx,wy; - m_window->screenToClient(x,y,wx,wy); - - if (m_rotation_settings[m_current_object].m_moving) { - m_rotation_settings[m_current_object].m_angle_x = MT_Scalar(wx)/20; - m_rotation_settings[m_current_object].x_old = wx; - m_rotation_settings[m_current_object].m_angle_y = MT_Scalar(wy)/20; - m_rotation_settings[m_current_object].y_old = wy; - - m_window->invalidate(); - } - if (m_translation_settings[m_current_object].m_moving) { - - // project current objects bounding box center into screen space. - // unproject mouse point into object space using z-value from - // projected bounding box center. - - GHOST_Rect bounds; - m_window->getClientBounds(bounds); - - int w_h = bounds.getHeight(); - - y = w_h - wy; - x = wx; - - double mvmatrix[16]; - double projmatrix[16]; - GLint viewport[4]; - - double px, py, pz,sz; - - /* Get the matrices needed for gluUnProject */ - glGetIntegerv(GL_VIEWPORT, viewport); - glGetDoublev(GL_MODELVIEW_MATRIX, mvmatrix); - glGetDoublev(GL_PROJECTION_MATRIX, projmatrix); - - // work out the position of the end effector in screen space - - GLdouble ex,ey,ez; - - ex = m_translation_settings[m_current_object].m_t_x; - ey = m_translation_settings[m_current_object].m_t_y; - ez = m_translation_settings[m_current_object].m_t_z; - - gluProject(ex, ey, ez, mvmatrix, projmatrix, viewport, &px, &py, &sz); - gluUnProject((GLdouble) x, (GLdouble) y, sz, mvmatrix, projmatrix, viewport, &px, &py, &pz); - - m_translation_settings[m_current_object].m_t_x = px; - m_translation_settings[m_current_object].m_t_y = py; - m_translation_settings[m_current_object].m_t_z = pz; - m_window->invalidate(); - - } - - handled = true; - break; - } - - case GHOST_kEventKeyDown : - { - GHOST_TEventKeyData *kd = - static_cast<GHOST_TEventKeyData *>(event->getData()); - - - switch(kd->key) { - case GHOST_kKeyI: - { - // now intersect meshes. - Operate(e_csg_intersection); - handled = true; - m_window->invalidate(); - break; - } - case GHOST_kKeyU: - { - Operate(e_csg_union); - handled = true; - m_window->invalidate(); - break; - } - case GHOST_kKeyD: - { - Operate(e_csg_difference); - handled = true; - m_window->invalidate(); - break; - } - - case GHOST_kKeyA: - { - - m_scale_settings[m_current_object] *= 1.1; - handled = true; - m_window->invalidate(); - break; - } - case GHOST_kKeyZ: - { - m_scale_settings[m_current_object] *= 0.8; - - handled = true; - m_window->invalidate(); - break; - } - - case GHOST_kKeyR: - m_render_modes[m_current_object]++; - if (m_render_modes[m_current_object] > e_last_render_mode) { - m_render_modes[m_current_object] = e_first_render_mode; - } - handled = true; - m_window->invalidate(); - break; - - case GHOST_kKeyB: - handled = true; - m_window->invalidate(); - break; - - case GHOST_kKeyQ: - m_finish_me_off = true; - handled = true; - break; - - case GHOST_kKeyS: - Swap(m_current_object); - m_window->invalidate(); - handled = true; - break; - - case GHOST_kKeySpace: - - // increment the current object only if the object is not being - // manipulated. - if (! (m_rotation_settings[m_current_object].m_moving || m_translation_settings[m_current_object].m_moving)) { - m_current_object ++; - if (m_current_object >= m_meshes.size()) { - m_current_object = 0; - - } - } - m_window->invalidate(); - handled = true; - break; - default : - break; - } - } - - default : - break; - } - return handled; -}; - -BSP_GhostTestApp3D:: -~BSP_GhostTestApp3D( -){ - - if (m_window) { - m_system->disposeWindow(m_window); - m_window = NULL; - GHOST_ISystem::disposeSystem(); - m_system = NULL; - } -}; - - - - void -BSP_GhostTestApp3D:: -DrawPolies( -){ - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - for (int i = 0; i < m_meshes.size(); ++i) { - MT_Transform trans = GetTransform(i); - - float opengl_mat[16]; - trans.getValue(opengl_mat); - - glPushMatrix(); - glMultMatrixf(opengl_mat); - MT_Vector3 color(1.0,1.0,1.0); - if (i == m_current_object) { - color = MT_Vector3(1.0,0,0); - } - BSP_MeshDrawer::DrawMesh(m_meshes[i].Ref(),m_render_modes[i]); - - glPopMatrix(); - } - - m_window->swapBuffers(); - -} - - void -BSP_GhostTestApp3D:: -InitOpenGl( - const MT_Vector3 &min, - const MT_Vector3 &max -){ - - GLfloat light_diffuse0[] = {1.0, 0.0, 0.0, 0.5}; /* Red diffuse light. */ - GLfloat light_position0[] = {1.0, 1.0, 1.0, 0.0}; /* Infinite light location. */ - - GLfloat light_diffuse1[] = {1.0, 1.0, 1.0, 0.5}; /* Red diffuse light. */ - GLfloat light_position1[] = {1.0, 0, 0, 0.0}; /* Infinite light location. */ - - /* Enable a single OpenGL light. */ - - glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse0); - glLightfv(GL_LIGHT0, GL_POSITION, light_position0); - - glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse1); - glLightfv(GL_LIGHT1, GL_POSITION, light_position1); - - - glEnable(GL_LIGHT0); - glEnable(GL_LIGHT1); - glEnable(GL_LIGHTING); - - // make sure there is no back face culling. - // glDisable(GL_CULL_FACE); - - // use two sided lighting model - glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,GL_TRUE); - - /* Use depth buffering for hidden surface elimination. */ - - glEnable(GL_DEPTH_TEST); - - /* Setup the view of the cube. */ - - glMatrixMode(GL_PROJECTION); - - // center of the box + 3* depth of box - - MT_Vector3 center = (min + max) * 0.5; - MT_Vector3 diag = max - min; - - float depth = diag.length(); - float distance = 5; - - gluPerspective( - /* field of view in degree */ 40.0, - /* aspect ratio */ 1.0, - /* Z near */ 1.0, - /* Z far */ distance * depth * 2 - ); - glMatrixMode(GL_MODELVIEW); - - gluLookAt( - center.x(), center.y(), center.z() + distance*depth, //eye - center.x(), center.y(), center.z(), //center - 0.0, 1.0, 0. - ); /* up is in positive Y direction */ - -} - - - - - - - - - - - - - - - - - - - - - diff --git a/intern/bsp/test/BSP_GhostTest/BSP_GhostTest3D.h b/intern/bsp/test/BSP_GhostTest/BSP_GhostTest3D.h deleted file mode 100644 index 8bfa6d061ee..00000000000 --- a/intern/bsp/test/BSP_GhostTest/BSP_GhostTest3D.h +++ /dev/null @@ -1,159 +0,0 @@ -/** - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#ifndef __BSP_GHOSTTEST3D_H__ -#define __BSP_GHOSTTEST3D_H__ - -#include "GHOST_IEventConsumer.h" -#include "MT_Vector3.h" -#include "BSP_TMesh.h" -#include "BSP_MeshDrawer.h" - -#include <vector> - -class GHOST_IWindow; -class GHOST_ISystem; - - -class BSP_GhostTestApp3D : -public GHOST_IEventConsumer -{ -public : - // Construct an instance of the application; - - BSP_GhostTestApp3D( - ); - - // initialize the applicaton - - bool - InitApp( - ); - - // Run the application untill internal return. - void - Run( - ); - - ~BSP_GhostTestApp3D( - ); - - void - SetMesh( - MEM_SmartPtr<BSP_TMesh> mesh - ); - -private : - - struct BSP_RotationSetting { - MT_Scalar m_angle_x; - MT_Scalar m_angle_y; - int x_old; - int y_old; - bool m_moving; - }; - - struct BSP_TranslationSetting { - MT_Scalar m_t_x; - MT_Scalar m_t_y; - MT_Scalar m_t_z; - int x_old; - int y_old; - bool m_moving; - }; - - // Return the transform of object i - - MT_Transform - GetTransform( - int active_object - ); - - // Perform an operation between the first two objects in the - // list - - void - Operate( - int type - ); - - // Swap mesh i and settings with the last mesh in list. - - void - Swap( - int i - ); - - void - DrawPolies( - ); - - void - UpdateFrame( - ); - - MT_Vector3 - UnProject( - const MT_Vector3 & vec - ); - - // Create a frustum and projection matrix to - // look at the bounding box - - void - InitOpenGl( - const MT_Vector3 &min, - const MT_Vector3 &max - ); - - - // inherited from GHOST_IEventConsumer - bool - processEvent( - GHOST_IEvent* event - ); - - GHOST_IWindow *m_window; - GHOST_ISystem *m_system; - - bool m_finish_me_off; - - // List of current meshes. - std::vector< MEM_SmartPtr<BSP_TMesh> > m_meshes; - - std::vector< BSP_RotationSetting> m_rotation_settings; - std::vector< BSP_TranslationSetting> m_translation_settings; - std::vector< MT_Scalar> m_scale_settings; - std::vector< int> m_render_modes; - - int m_current_object; - - -}; - -#endif - diff --git a/intern/bsp/test/BSP_GhostTest/BSP_MeshDrawer.cpp b/intern/bsp/test/BSP_GhostTest/BSP_MeshDrawer.cpp deleted file mode 100644 index a1a3150c4d4..00000000000 --- a/intern/bsp/test/BSP_GhostTest/BSP_MeshDrawer.cpp +++ /dev/null @@ -1,156 +0,0 @@ -/** - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#include "BSP_MeshDrawer.h" - -#include "BSP_TMesh.h" - -#if defined(WIN32) || defined(__APPLE__) -# ifdef WIN32 -# include <windows.h> -# include <GL/gl.h> -# include <GL/glu.h> -# else // WIN32 -# include <AGL/gl.h> -# endif // WIN32 -#else // defined(WIN32) || defined(__APPLE__) -# include <GL/gl.h> -# include <GL/glu.h> -#endif // defined(WIN32) || defined(__APPLE__) - -#include <vector> - -using namespace std; - - void -BSP_MeshDrawer:: -DrawMesh( - BSP_TMesh &mesh, - int render_mode -){ - - - if (render_mode == e_none) return; - - // decompose polygons into triangles. - - glEnable(GL_LIGHTING); - - - if (render_mode == e_wireframe || render_mode == e_wireframe_shaded) { - - glColor3f(0.0, 0.0, 0.0); - - if (render_mode == e_wireframe) { - glDisable(GL_LIGHTING); - } else { - glEnable(GL_LIGHTING); - } - - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - - glEnable(GL_POLYGON_OFFSET_FILL); - glPolygonOffset(1.0,1.0); - - glBegin(GL_TRIANGLES); - DrawPolies(mesh); - glEnd(); - - glColor3f(1.0, 1.0, 1.0); - glDisable(GL_LIGHTING); - glDisable(GL_POLYGON_OFFSET_FILL); - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - - glBegin(GL_TRIANGLES); - DrawPolies(mesh); - glEnd(); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - } else { - - glEnable(GL_LIGHTING); - - glBegin(GL_TRIANGLES); - DrawPolies(mesh); - glEnd(); - } - - -} - - - void -BSP_MeshDrawer:: -DrawPolies( - BSP_TMesh &mesh -){ - - const vector<BSP_TVertex> & verts = mesh.VertexSet(); - const vector<BSP_TFace> &faces = mesh.FaceSet(); - - // just draw the edges for now. - - vector<BSP_TVertex>::const_iterator vertex_it = verts.begin(); - - - vector<BSP_TFace>::const_iterator faces_it = faces.begin(); - vector<BSP_TFace>::const_iterator faces_end = faces.end(); - - for (;faces_it != faces_end; ++faces_it ){ - - glNormal3f( - faces_it->m_normal.x(), - faces_it->m_normal.y(), - faces_it->m_normal.z() - ); - - glVertex3f( - verts[faces_it->m_verts[0]].m_pos.x(), - verts[faces_it->m_verts[0]].m_pos.y(), - verts[faces_it->m_verts[0]].m_pos.z() - ); - glVertex3f( - verts[faces_it->m_verts[1]].m_pos.x(), - verts[faces_it->m_verts[1]].m_pos.y(), - verts[faces_it->m_verts[1]].m_pos.z() - ); - glVertex3f( - verts[faces_it->m_verts[2]].m_pos.x(), - verts[faces_it->m_verts[2]].m_pos.y(), - verts[faces_it->m_verts[2]].m_pos.z() - ); - } -} - - - - - - - - - - diff --git a/intern/bsp/test/BSP_GhostTest/BSP_MeshDrawer.h b/intern/bsp/test/BSP_GhostTest/BSP_MeshDrawer.h deleted file mode 100644 index 17aeccc603a..00000000000 --- a/intern/bsp/test/BSP_GhostTest/BSP_MeshDrawer.h +++ /dev/null @@ -1,71 +0,0 @@ -/** - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#ifndef __BSP_MESHDRAWER_H__ -#define __BSP_MESHDRAWER_H__ - -class BSP_TMesh; -class MT_Vector3; - -enum BSP_TRenderMode { - e_shaded, - e_none, - e_wireframe, - e_wireframe_shaded, - e_first_render_mode = e_shaded, - e_last_render_mode = e_wireframe_shaded -}; - -class BSP_MeshDrawer -{ -public : - static - void - DrawMesh( - BSP_TMesh &mesh, - int render_mode - ); - -private : - - static - void - DrawPolies( - BSP_TMesh &mesh - ); - - - BSP_MeshDrawer( - ); - - ~BSP_MeshDrawer( - ); - -}; - -#endif - diff --git a/intern/bsp/test/BSP_GhostTest/BSP_PlyLoader.cpp b/intern/bsp/test/BSP_GhostTest/BSP_PlyLoader.cpp deleted file mode 100644 index 65a1da34a9b..00000000000 --- a/intern/bsp/test/BSP_GhostTest/BSP_PlyLoader.cpp +++ /dev/null @@ -1,192 +0,0 @@ -/** - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#include "BSP_PlyLoader.h" - -#include "MT_Vector3.h" -#include "ply.h" - -struct LoadVertex { - float x,y,z; /* the usual 3-space position of a vertex */ -}; - -struct LoadFace { - unsigned char intensity; /* this user attaches intensity to faces */ - unsigned char nverts; /* number of vertex indices in list */ - int *verts; /* vertex index list */ -}; - - - MEM_SmartPtr<BSP_TMesh> -BSP_PlyLoader:: -NewMeshFromFile( - char * file_name, - MT_Vector3 &min, - MT_Vector3 &max - -) { - - min = MT_Vector3(MT_INFINITY,MT_INFINITY,MT_INFINITY); - max = MT_Vector3(-MT_INFINITY,-MT_INFINITY,-MT_INFINITY); - - PlyProperty vert_props[] = { /* list of property information for a vertex */ - {"x", PLY_FLOAT, PLY_FLOAT, offsetof(LoadVertex,x), 0, 0, 0, 0}, - {"y", PLY_FLOAT, PLY_FLOAT, offsetof(LoadVertex,y), 0, 0, 0, 0}, - {"z", PLY_FLOAT, PLY_FLOAT, offsetof(LoadVertex,z), 0, 0, 0, 0}, - }; - - PlyProperty face_props[] = { /* list of property information for a vertex */ - {"vertex_indices", PLY_INT, PLY_INT, offsetof(LoadFace,verts), - 1, PLY_UCHAR, PLY_UCHAR, offsetof(LoadFace,nverts)}, - }; - - MEM_SmartPtr<BSP_TMesh> mesh = new BSP_TMesh; - - if (mesh == NULL) return NULL; - - int i,j; - PlyFile *ply; - int nelems; - char **elist; - int file_type; - float version; - int nprops; - int num_elems; - PlyProperty **plist; - - char *elem_name; - - LoadVertex load_vertex; - LoadFace load_face; - - /* open a PLY file for reading */ - ply = ply_open_for_reading( - file_name, - &nelems, - &elist, - &file_type, - &version - ); - - if (ply == NULL) return NULL; - - /* go through each kind of element that we learned is in the file */ - /* and read them */ - - for (i = 0; i < nelems; i++) { - - /* get the description of the first element */ - - elem_name = elist[i]; - plist = ply_get_element_description (ply, elem_name, &num_elems, &nprops); - - /* print the name of the element, for debugging */ - - /* if we're on vertex elements, read them in */ - - if (equal_strings ("vertex", elem_name)) { - - /* set up for getting vertex elements */ - - ply_get_property (ply, elem_name, &vert_props[0]); - ply_get_property (ply, elem_name, &vert_props[1]); - ply_get_property (ply, elem_name, &vert_props[2]); - - // make some memory for the vertices - mesh->VertexSet().reserve(num_elems); - - /* grab all the vertex elements */ - for (j = 0; j < num_elems; j++) { - - /* grab and element from the file */ - ply_get_element (ply, (void *)&load_vertex); - // pass the vertex into the mesh builder. - - if (load_vertex.x < min.x()) { - min.x() = load_vertex.x; - } else - if (load_vertex.x > max.x()) { - max.x()= load_vertex.x; - } - - if (load_vertex.y < min.y()) { - min.y() = load_vertex.y; - } else - if (load_vertex.y > max.y()) { - max.y()= load_vertex.y; - } - - if (load_vertex.z < min.z()) { - min.z() = load_vertex.z; - } else - if (load_vertex.z > max.z()) { - max.z()= load_vertex.z; - } - - BSP_TVertex my_vert; - my_vert.m_pos = MT_Vector3(load_vertex.x,load_vertex.y,load_vertex.z); - mesh->VertexSet().push_back(my_vert); - } - - - } - - /* if we're on face elements, read them in */ - if (equal_strings ("face", elem_name)) { - - /* set up for getting face elements */ - - ply_get_property (ply, elem_name, &face_props[0]); - - /* grab all the face elements */ - for (j = 0; j < num_elems; j++) { - - ply_get_element (ply, (void *)&load_face); - - int v; - for (v = 2; v< load_face.nverts; v++) { - - BSP_TFace f; - - f.m_verts[0] = load_face.verts[0]; - f.m_verts[1] = load_face.verts[v-1]; - f.m_verts[2] = load_face.verts[v]; - - mesh->BuildNormal(f); - mesh->FaceSet().push_back(f); - } - // free up the memory this pile of shit used to allocate the polygon's vertices - free (load_face.verts); - } - - } - } - /* close the PLY file */ - ply_close (ply); - - return mesh; -} diff --git a/intern/bsp/test/BSP_GhostTest/BSP_PlyLoader.h b/intern/bsp/test/BSP_GhostTest/BSP_PlyLoader.h deleted file mode 100644 index 8fcac29253b..00000000000 --- a/intern/bsp/test/BSP_GhostTest/BSP_PlyLoader.h +++ /dev/null @@ -1,60 +0,0 @@ -/** - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#ifndef __BSP_PLYLOADER_H__ -#define __BSP_PLYLOADER_H__ - -#include "MEM_SmartPtr.h" -#include "BSP_TMesh.h" - -class BSP_PlyLoader { -public : - - static - MEM_SmartPtr<BSP_TMesh> - NewMeshFromFile( - char * file_name, - MT_Vector3 &min, - MT_Vector3 &max - ); - - -private : - - // unimplemented - not for instantiation. - - BSP_PlyLoader( - ); - - ~BSP_PlyLoader( - ); -}; - - - -#endif - diff --git a/intern/bsp/test/BSP_GhostTest/BSP_TMesh.h b/intern/bsp/test/BSP_GhostTest/BSP_TMesh.h deleted file mode 100644 index 793fb47f73b..00000000000 --- a/intern/bsp/test/BSP_GhostTest/BSP_TMesh.h +++ /dev/null @@ -1,397 +0,0 @@ -/** - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#ifndef __BSP_TMESH_H__ -#define __BSP_TMESH_H__ - -#include "MT_Point3.h" -#include "MT_Vector3.h" -#include "MT_Transform.h" - -#include "MEM_SmartPtr.h" - -#include <vector> - -#include "CSG_BooleanOps.h" - -/** - * A very basic test mesh. - */ - -struct BSP_TVertex { - MT_Point3 m_pos; -}; - -struct BSP_TFace { - int m_verts[3]; - MT_Vector3 m_normal; -}; - - -class BSP_TMesh { -public : - - std::vector<BSP_TVertex> m_verts; - std::vector<BSP_TFace> m_faces; - - MT_Vector3 m_min,m_max; - - std::vector<BSP_TVertex> & - VertexSet( - ){ - return m_verts; - } - - std::vector<BSP_TFace> & - FaceSet( - ) { - return m_faces; - } - - void - AddFace( - int *verts, - int num_verts - ){ - int i; - for (i= 2; i <num_verts; i++) { - BSP_TFace f; - f.m_verts[0] = verts[0]; - f.m_verts[1] = verts[i-1]; - f.m_verts[2] = verts[i]; - - m_faces.push_back(f); - - BuildNormal(m_faces.back()); - } - } - - void - BuildNormal( - BSP_TFace & f - ) const { - MT_Vector3 l1 = - m_verts[f.m_verts[1]].m_pos - - m_verts[f.m_verts[0]].m_pos; - MT_Vector3 l2 = - m_verts[f.m_verts[2]].m_pos - - m_verts[f.m_verts[1]].m_pos; - - MT_Vector3 normal = l1.cross(l2); - - f.m_normal = normal.safe_normalized(); - } - -}; - - - -/** - * some iterator functions to describe the mesh to the BSP module. - */ - -/** - * This class defines 2 C style iterators over a CSG mesh, one for - * vertices and 1 for faces. They conform to the iterator interface - * defined in CSG_BooleanOps.h - */ - -struct VertexIt { - BSP_TMesh * mesh; - BSP_TVertex * pos; - MT_Transform trans; -}; - - -static - void -VertexIt_Destruct( - CSG_VertexIteratorDescriptor * iterator -) { - delete ((VertexIt *)(iterator->it)); - iterator->it = NULL; - delete(iterator); -}; - - -static - int -VertexIt_Done( - CSG_IteratorPtr it -) { - // assume CSG_IteratorPtr is of the correct type. - VertexIt * vertex_it = (VertexIt *)it; - - if (vertex_it->pos < vertex_it->mesh->VertexSet().end()) return 0; - return 1; -}; - -static - void -VertexIt_Fill( - CSG_IteratorPtr it, - CSG_IVertex *vert -) { - // assume CSG_IteratorPtr is of the correct type. - VertexIt * vertex_it = (VertexIt *)it; - - MT_Point3 p = vertex_it->pos->m_pos; - p = vertex_it->trans * p; - - p.getValue(vert->position); -}; - -static - void -VertexIt_Step( - CSG_IteratorPtr it -) { - // assume CSG_IteratorPtr is of the correct type. - VertexIt * vertex_it = (VertexIt *)it; - - ++(vertex_it->pos); -}; - -static - void -VertexIt_Reset( - CSG_IteratorPtr it -) { - // assume CSG_IteratorPtr is of the correct type. - VertexIt * vertex_it = (VertexIt *)it; - - vertex_it->pos = vertex_it->mesh->VertexSet().begin(); -}; - -static - CSG_VertexIteratorDescriptor * -VertexIt_Construct( - BSP_TMesh *mesh, - MT_Transform trans -){ - // user should have insured mesh is not equal to NULL. - - CSG_VertexIteratorDescriptor * output = new CSG_VertexIteratorDescriptor; - if (output == NULL) return NULL; - output->Done = VertexIt_Done; - output->Fill = VertexIt_Fill; - output->Step = VertexIt_Step; - output->Reset = VertexIt_Reset; - output->num_elements = mesh->VertexSet().size(); - - VertexIt * v_it = new VertexIt; - v_it->mesh = mesh; - v_it->pos = mesh->VertexSet().begin(); - v_it->trans = trans; - output->it = v_it; - return output; -}; - - -/** - * Face iterator. - */ - -struct FaceIt { - BSP_TMesh * mesh; - BSP_TFace *pos; -}; - - -static - void -FaceIt_Destruct( - CSG_FaceIteratorDescriptor * iterator -) { - delete ((FaceIt *)(iterator->it)); - iterator->it = NULL; - delete(iterator); -}; - - -static - int -FaceIt_Done( - CSG_IteratorPtr it -) { - // assume CSG_IteratorPtr is of the correct type. - FaceIt * face_it = (FaceIt *)it; - - if (face_it->pos < face_it->mesh->FaceSet().end()) { - return 0; - } - return 1; -}; - -static - void -FaceIt_Fill( - CSG_IteratorPtr it, - CSG_IFace *face -){ - // assume CSG_IteratorPtr is of the correct type. - FaceIt * face_it = (FaceIt *)it; - // essentially iterating through a triangle fan here. - - face->vertex_index[0] = int(face_it->pos->m_verts[0]); - face->vertex_index[1] = int(face_it->pos->m_verts[1]); - face->vertex_index[2] = int(face_it->pos->m_verts[2]); - - face->vertex_number = 3; -}; - -static - void -FaceIt_Step( - CSG_IteratorPtr it -) { - // assume CSG_IteratorPtr is of the correct type. - FaceIt * face_it = (FaceIt *)it; - - face_it->pos ++; -}; - -static - void -FaceIt_Reset( - CSG_IteratorPtr it -) { - // assume CSG_IteratorPtr is of the correct type. - FaceIt * face_it = (FaceIt *)it; - - face_it->pos = face_it->mesh->FaceSet().begin(); -}; - -static - CSG_FaceIteratorDescriptor * -FaceIt_Construct( - BSP_TMesh * mesh -) { - CSG_FaceIteratorDescriptor * output = new CSG_FaceIteratorDescriptor; - if (output == NULL) return NULL; - - output->Done = FaceIt_Done; - output->Fill = FaceIt_Fill; - output->Step = FaceIt_Step; - output->Reset = FaceIt_Reset; - - output->num_elements = mesh->FaceSet().size(); - - FaceIt * f_it = new FaceIt; - f_it->mesh = mesh; - f_it->pos = mesh->FaceSet().begin(); - - output->it = f_it; - - return output; -}; - -/** - * Some Build functions. - */ - -static - MEM_SmartPtr<BSP_TMesh> -BuildMesh( - CSG_MeshPropertyDescriptor &props, - CSG_FaceIteratorDescriptor &face_it, - CSG_VertexIteratorDescriptor &vertex_it -) { - MEM_SmartPtr<BSP_TMesh> mesh = new BSP_TMesh(); - - CSG_IVertex vert; - - while (!vertex_it.Done(vertex_it.it)) { - - vertex_it.Fill(vertex_it.it,&vert); - - BSP_TVertex v; - v.m_pos = MT_Point3(vert.position); - mesh->VertexSet().push_back(v); - - vertex_it.Step(vertex_it.it); - } - - - CSG_IFace face; - - while (!face_it.Done(face_it.it)) { - face_it.Fill(face_it.it,&face); - - BSP_TFace f; - - f.m_verts[0] = face.vertex_index[0], - f.m_verts[1] = face.vertex_index[1], - f.m_verts[2] = face.vertex_index[2], - - mesh->BuildNormal(f); - - mesh->FaceSet().push_back(f); - - face_it.Step(face_it.it); - } - - return mesh; -}; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -#endif - diff --git a/intern/bsp/test/BSP_GhostTest/main.cpp b/intern/bsp/test/BSP_GhostTest/main.cpp deleted file mode 100644 index 25185f40192..00000000000 --- a/intern/bsp/test/BSP_GhostTest/main.cpp +++ /dev/null @@ -1,143 +0,0 @@ -/** - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#include "BSP_GhostTest3D.h" - -#include "BSP_TMesh.h" -#include "MEM_SmartPtr.h" -#include "BSP_PlyLoader.h" - -#include <iostream> - -using namespace std; -#if 1 - MEM_SmartPtr<BSP_TMesh> -NewTestMesh( - int x, - int y, - MT_Scalar fx, - MT_Scalar fy, - MT_Scalar ampx, - MT_Scalar ampy, - MT_Scalar sx, - MT_Scalar sy -) { - - MEM_SmartPtr<BSP_TMesh> output = new BSP_TMesh; - - std::vector<BSP_TVertex> &verts = output->VertexSet(); - - int i,j; - - MT_Scalar x_scale = fx*MT_PI/x; - MT_Scalar y_scale = fy*MT_PI/y; - - MT_Scalar fsx = sx/x; - MT_Scalar fsy = sy/y; - - for (j = 0; j < y; j++) { - for (i = 0; i < x; i++) { - float z = ampx*sin(x_scale * i) + ampy*sin(y_scale * j); - - MT_Vector3 val(i*fsx - sx/2,j*fsy - sy/2,z); - - BSP_TVertex chuff; - chuff.m_pos = val; - verts.push_back(chuff); - } - } - - int poly[4]; - - for (j = 0; j < (y-1); j++) { - for (i = 0; i < (x-1); i++) { - - poly[0] = j*x + i; - poly[1] = poly[0] + 1; - poly[2] = poly[1] + y; - poly[3] = poly[2] -1; - - output->AddFace(poly,4); - } - } - - output->m_min = MT_Vector3(-sx/2,-sy/2,-ampx -ampy); - output->m_max = MT_Vector3(sx/2,sy/2,ampx + ampy); - - return output; -} -#endif - - -int main() -{ - MT_Vector3 min,max; - MT_Vector3 min2,max2; - -#if 1 - MEM_SmartPtr<BSP_TMesh> mesh1 = BSP_PlyLoader::NewMeshFromFile("bsp_cube.ply",min,max); - MEM_SmartPtr<BSP_TMesh> mesh2 = BSP_PlyLoader::NewMeshFromFile("bsp_cube.ply",min2,max2); - - mesh1->m_min = min; - mesh1->m_max = max; - mesh2->m_min = min2; - mesh1->m_max = max2; - -#else - MEM_SmartPtr<BSP_TMesh> mesh1 = NewTestMesh(10,10,2,2,4,4,20,20); - MEM_SmartPtr<BSP_TMesh> mesh2 = NewTestMesh(10,10,2,2,4,4,20,20); -#endif - - if (!mesh1) { - cout << "could not load mesh!"; - return 0; - } - - - -// MEM_SmartPtr<BSP_TMesh> mesh2 = new BSP_TMesh(mesh1.Ref()); - - BSP_GhostTestApp3D app; - - cout << "Mesh polygons :" << mesh1->FaceSet().size() << "\n"; - cout << "Mesh vertices :" << mesh1->VertexSet().size() << "\n"; - - app.SetMesh(mesh1); - app.SetMesh(mesh2); - - - app.InitApp(); - - app.Run(); - - return 0; - -} - - - - diff --git a/intern/bsp/test/BSP_GhostTest/ply.h b/intern/bsp/test/BSP_GhostTest/ply.h deleted file mode 100644 index 12425ded898..00000000000 --- a/intern/bsp/test/BSP_GhostTest/ply.h +++ /dev/null @@ -1,196 +0,0 @@ -/** - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/* - -Header for PLY polygon files. - -- Greg Turk, March 1994 - -A PLY file contains a single polygonal _object_. - -An object is composed of lists of _elements_. Typical elements are -vertices, faces, edges and materials. - -Each type of element for a given object has one or more _properties_ -associated with the element type. For instance, a vertex element may -have as properties three floating-point values x,y,z and three unsigned -chars for red, green and blue. - ---------------------------------------------------------------- - -Copyright (c) 1994 The Board of Trustees of The Leland Stanford -Junior University. All rights reserved. - -Permission to use, copy, modify and distribute this software and its -documentation for any purpose is hereby granted without fee, provided -that the above copyright notice and this permission notice appear in -all copies of this software and that you do not sell the software. - -THE SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTY OF ANY KIND, -EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY -WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - -*/ - -#ifndef __PLY_H__ -#define __PLY_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include <stdio.h> -#include <stddef.h> - -#define PLY_ASCII 1 /* ascii PLY file */ -#define PLY_BINARY_BE 2 /* binary PLY file, big endian */ -#define PLY_BINARY_LE 3 /* binary PLY file, little endian */ - -#define PLY_OKAY 0 /* ply routine worked okay */ -#define PLY_ERROR -1 /* error in ply routine */ - -/* scalar data types supported by PLY format */ - -#define PLY_START_TYPE 0 -#define PLY_CHAR 1 -#define PLY_SHORT 2 -#define PLY_INT 3 -#define PLY_UCHAR 4 -#define PLY_USHORT 5 -#define PLY_UINT 6 -#define PLY_FLOAT 7 -#define PLY_DOUBLE 8 -#define PLY_END_TYPE 9 - -#define PLY_SCALAR 0 -#define PLY_LIST 1 - - -typedef struct PlyProperty { /* description of a property */ - - char *name; /* property name */ - int external_type; /* file's data type */ - int internal_type; /* program's data type */ - int offset; /* offset bytes of prop in a struct */ - - int is_list; /* 1 = list, 0 = scalar */ - int count_external; /* file's count type */ - int count_internal; /* program's count type */ - int count_offset; /* offset byte for list count */ - -} PlyProperty; - -typedef struct PlyElement { /* description of an element */ - char *name; /* element name */ - int num; /* number of elements in this object */ - int size; /* size of element (bytes) or -1 if variable */ - int nprops; /* number of properties for this element */ - PlyProperty **props; /* list of properties in the file */ - char *store_prop; /* flags: property wanted by user? */ - int other_offset; /* offset to un-asked-for props, or -1 if none*/ - int other_size; /* size of other_props structure */ -} PlyElement; - -typedef struct PlyOtherProp { /* describes other properties in an element */ - char *name; /* element name */ - int size; /* size of other_props */ - int nprops; /* number of properties in other_props */ - PlyProperty **props; /* list of properties in other_props */ -} PlyOtherProp; - -typedef struct OtherData { /* for storing other_props for an other element */ - void *other_props; -} OtherData; - -typedef struct OtherElem { /* data for one "other" element */ - char *elem_name; /* names of other elements */ - int elem_count; /* count of instances of each element */ - OtherData **other_data; /* actual property data for the elements */ - PlyOtherProp *other_props; /* description of the property data */ -} OtherElem; - -typedef struct PlyOtherElems { /* "other" elements, not interpreted by user */ - int num_elems; /* number of other elements */ - OtherElem *other_list; /* list of data for other elements */ -} PlyOtherElems; - -typedef struct PlyFile { /* description of PLY file */ - FILE *fp; /* file pointer */ - int file_type; /* ascii or binary */ - float version; /* version number of file */ - int nelems; /* number of elements of object */ - PlyElement **elems; /* list of elements */ - int num_comments; /* number of comments */ - char **comments; /* list of comments */ - int num_obj_info; /* number of items of object information */ - char **obj_info; /* list of object info items */ - PlyElement *which_elem; /* which element we're currently writing */ - PlyOtherElems *other_elems; /* "other" elements from a PLY file */ -} PlyFile; - -/* memory allocation */ -static char *my_alloc(); -#define myalloc(mem_size) my_alloc((mem_size), __LINE__, __FILE__) - - -/*** delcaration of routines ***/ - -extern PlyFile *ply_write(FILE *, int, char **, int); -extern PlyFile *ply_open_for_writing(char *, int, char **, int, float *); -extern void ply_describe_element(PlyFile *, char *, int, int, PlyProperty *); -extern void ply_describe_property(PlyFile *, char *, PlyProperty *); -extern void ply_element_count(PlyFile *, char *, int); -extern void ply_header_complete(PlyFile *); -extern void ply_put_element_setup(PlyFile *, char *); -extern void ply_put_element(PlyFile *, void *); -extern void ply_put_comment(PlyFile *, char *); -extern void ply_put_obj_info(PlyFile *, char *); -extern PlyFile *ply_read(FILE *, int *, char ***); -extern PlyFile *ply_open_for_reading( char *, int *, char ***, int *, float *); -extern PlyProperty **ply_get_element_description(PlyFile *, char *, int*, int*); -extern void ply_get_element_setup( PlyFile *, char *, int, PlyProperty *); -extern void ply_get_property(PlyFile *, char *, PlyProperty *); -extern PlyOtherProp *ply_get_other_properties(PlyFile *, char *, int); -extern void ply_get_element(PlyFile *, void *); -extern char **ply_get_comments(PlyFile *, int *); -extern char **ply_get_obj_info(PlyFile *, int *); -extern void ply_close(PlyFile *); -extern void ply_get_info(PlyFile *, float *, int *); -extern PlyOtherElems *ply_get_other_element (PlyFile *, char *, int); -extern void ply_describe_other_elements ( PlyFile *, PlyOtherElems *); -extern void ply_put_other_elements (PlyFile *); -extern void ply_free_other_elements (PlyOtherElems *); - -extern int equal_strings(char *, char *); - - -#ifdef __cplusplus -} -#endif -#endif /* !__PLY_H__ */ - diff --git a/intern/bsp/test/BSP_GhostTest/plyfile.c b/intern/bsp/test/BSP_GhostTest/plyfile.c deleted file mode 100644 index b0134f06557..00000000000 --- a/intern/bsp/test/BSP_GhostTest/plyfile.c +++ /dev/null @@ -1,2545 +0,0 @@ -/** - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/* - - - The interface routines for reading and writing PLY polygon files. - - Greg Turk, February 1994 - - --------------------------------------------------------------- - - A PLY file contains a single polygonal _object_. - - An object is composed of lists of _elements_. Typical elements are - vertices, faces, edges and materials. - - Each type of element for a given object has one or more _properties_ - associated with the element type. For instance, a vertex element may - have as properties the floating-point values x,y,z and the three unsigned - chars representing red, green and blue. - - --------------------------------------------------------------- - - Copyright (c) 1994 The Board of Trustees of The Leland Stanford - Junior University. All rights reserved. - - Permission to use, copy, modify and distribute this software and its - documentation for any purpose is hereby granted without fee, provided - that the above copyright notice and this permission notice appear in - all copies of this software and that you do not sell the software. - - THE SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTY OF ANY KIND, - EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - - */ - -#include <stdio.h> -#include <stdlib.h> -#include <math.h> -#include <string.h> -#include "ply.h" - -char *type_names[] = { - "invalid", - "char", "short", "int", - "uchar", "ushort", "uint", - "float", "double", -}; - -int ply_type_size[] = { - 0, 1, 2, 4, 1, 2, 4, 4, 8 -}; - -#define NO_OTHER_PROPS -1 - -#define DONT_STORE_PROP 0 -#define STORE_PROP 1 - -#define OTHER_PROP 0 -#define NAMED_PROP 1 - - -/* returns 1 if strings are equal, 0 if not */ -int equal_strings(char *, char *); - -/* find an element in a plyfile's list */ -PlyElement *find_element(PlyFile *, char *); - -/* find a property in an element's list */ -PlyProperty *find_property(PlyElement *, char *, int *); - -/* write to a file the word describing a PLY file data type */ -void write_scalar_type(FILE *, int); - -/* read a line from a file and break it up into separate words */ -char **get_words(FILE *, int *, char **); -char **old_get_words(FILE *, int *); - -/* write an item to a file */ -void write_binary_item(FILE *, int, unsigned int, double, int); -void write_ascii_item(FILE *, int, unsigned int, double, int); -double old_write_ascii_item(FILE *, char *, int); - -/* add information to a PLY file descriptor */ -void add_element(PlyFile *, char **); -void add_property(PlyFile *, char **); -void add_comment(PlyFile *, char *); -void add_obj_info(PlyFile *, char *); - -/* copy a property */ -void copy_property(PlyProperty *, PlyProperty *); - -/* store a value into where a pointer and a type specify */ -void store_item(char *, int, int, unsigned int, double); - -/* return the value of a stored item */ -void get_stored_item(void *, int, int *, unsigned int *, double *); - -/* return the value stored in an item, given ptr to it and its type */ -double get_item_value(char *, int); - -/* get binary or ascii item and store it according to ptr and type */ -void get_ascii_item(char *, int, int *, unsigned int *, double *); -void get_binary_item(FILE *, int, int *, unsigned int *, double *); - -/* get a bunch of elements from a file */ -void ascii_get_element(PlyFile *, char *); -void binary_get_element(PlyFile *, char *); - -/* memory allocation */ -char *my_alloc(int, int, char *); - - -/*************/ -/* Writing */ -/*************/ - - -/****************************************************************************** - Given a file pointer, get ready to write PLY data to the file. - - Entry: - fp - the given file pointer - nelems - number of elements in object - elem_names - list of element names - file_type - file type, either ascii or binary - - Exit: - returns a pointer to a PlyFile, used to refer to this file, or NULL if error -******************************************************************************/ - -PlyFile *ply_write( - FILE *fp, - int nelems, - char **elem_names, - int file_type - ) -{ - int i; - PlyFile *plyfile; - PlyElement *elem; - - /* check for NULL file pointer */ - if (fp == NULL) - return (NULL); - - /* create a record for this object */ - - plyfile = (PlyFile *) myalloc(sizeof(PlyFile)); - plyfile->file_type = file_type; - plyfile->num_comments = 0; - plyfile->num_obj_info = 0; - plyfile->nelems = nelems; - plyfile->version = 1.0; - plyfile->fp = fp; - plyfile->other_elems = NULL; - - /* tuck aside the names of the elements */ - - plyfile->elems = (PlyElement **) myalloc(sizeof(PlyElement *) * nelems); - for (i = 0; i < nelems; i++) { - elem = (PlyElement *) myalloc(sizeof(PlyElement)); - plyfile->elems[i] = elem; - elem->name = strdup(elem_names[i]); - elem->num = 0; - elem->nprops = 0; - } - - /* return pointer to the file descriptor */ - return (plyfile); -} - - -/****************************************************************************** - Open a polygon file for writing. - - Entry: - filename - name of file to read from - nelems - number of elements in object - elem_names - list of element names - file_type - file type, either ascii or binary - - Exit: - version - version number of PLY file - returns a file identifier, used to refer to this file, or NULL if error -******************************************************************************/ - -PlyFile *ply_open_for_writing( - char *filename, - int nelems, - char **elem_names, - int file_type, - float *version - ) -{ - PlyFile *plyfile; - char *name; - FILE *fp; - - /* tack on the extension .ply, if necessary */ - - name = (char *) myalloc(sizeof(char) * (strlen(filename) + 5)); - strcpy(name, filename); - if (strlen(name) < 4 || - strcmp(name + strlen(name) - 4, ".ply") != 0) - strcat(name, ".ply"); - - /* open the file for writing */ - - fp = fopen(name, "w"); - if (fp == NULL) { - return (NULL); - } - - /* create the actual PlyFile structure */ - - plyfile = ply_write(fp, nelems, elem_names, file_type); - if (plyfile == NULL) - return (NULL); - - /* say what PLY file version number we're writing */ - *version = plyfile->version; - - /* return pointer to the file descriptor */ - return (plyfile); -} - - -/****************************************************************************** - Describe an element, including its properties and how many will be written - to the file. - - Entry: - plyfile - file identifier - elem_name - name of element that information is being specified about - nelems - number of elements of this type to be written - nprops - number of properties contained in the element - prop_list - list of properties -******************************************************************************/ - -void ply_describe_element( - PlyFile *plyfile, - char *elem_name, - int nelems, - int nprops, - PlyProperty *prop_list - ) -{ - int i; - PlyElement *elem; - PlyProperty *prop; - - /* look for appropriate element */ - elem = find_element(plyfile, elem_name); - if (elem == NULL) { - fprintf(stderr, "ply_describe_element: can't find element '%s'\n", elem_name); - exit(-1); - } - - elem->num = nelems; - - /* copy the list of properties */ - - elem->nprops = nprops; - elem->props = (PlyProperty **) myalloc(sizeof(PlyProperty *) * nprops); - elem->store_prop = (char *) myalloc(sizeof(char) * nprops); - - for (i = 0; i < nprops; i++) { - prop = (PlyProperty *) myalloc(sizeof(PlyProperty)); - elem->props[i] = prop; - elem->store_prop[i] = NAMED_PROP; - copy_property(prop, &prop_list[i]); - } -} - - -/****************************************************************************** - Describe a property of an element. - - Entry: - plyfile - file identifier - elem_name - name of element that information is being specified about - prop - the new property -******************************************************************************/ - -void ply_describe_property( - PlyFile *plyfile, - char *elem_name, - PlyProperty *prop - ) -{ - PlyElement *elem; - PlyProperty *elem_prop; - - /* look for appropriate element */ - elem = find_element(plyfile, elem_name); - if (elem == NULL) { - fprintf(stderr, "ply_describe_property: can't find element '%s'\n", - elem_name); - return; - } - - /* create room for new property */ - - if (elem->nprops == 0) { - elem->props = (PlyProperty **) myalloc(sizeof(PlyProperty *)); - elem->store_prop = (char *) myalloc(sizeof(char)); - elem->nprops = 1; - } - else { - elem->nprops++; - elem->props = (PlyProperty **) - realloc(elem->props, sizeof(PlyProperty *) * elem->nprops); - elem->store_prop = (char *) - realloc(elem->store_prop, sizeof(char) * elem->nprops); - } - - /* copy the new property */ - - elem_prop = (PlyProperty *) myalloc(sizeof(PlyProperty)); - elem->props[elem->nprops - 1] = elem_prop; - elem->store_prop[elem->nprops - 1] = NAMED_PROP; - copy_property(elem_prop, prop); -} - - -/****************************************************************************** - Describe what the "other" properties are that are to be stored, and where - they are in an element. -******************************************************************************/ - -void ply_describe_other_properties( - PlyFile *plyfile, - PlyOtherProp *other, - int offset - ) -{ - int i; - PlyElement *elem; - PlyProperty *prop; - - /* look for appropriate element */ - elem = find_element(plyfile, other->name); - if (elem == NULL) { - fprintf(stderr, "ply_describe_other_properties: can't find element '%s'\n", - other->name); - return; - } - - /* create room for other properties */ - - if (elem->nprops == 0) { - elem->props = (PlyProperty **) - myalloc(sizeof(PlyProperty *) * other->nprops); - elem->store_prop = (char *) myalloc(sizeof(char) * other->nprops); - elem->nprops = 0; - } - else { - int newsize; - newsize = elem->nprops + other->nprops; - elem->props = (PlyProperty **) - realloc(elem->props, sizeof(PlyProperty *) * newsize); - elem->store_prop = (char *) - realloc(elem->store_prop, sizeof(char) * newsize); - } - - /* copy the other properties */ - - for (i = 0; i < other->nprops; i++) { - prop = (PlyProperty *) myalloc(sizeof(PlyProperty)); - copy_property(prop, other->props[i]); - elem->props[elem->nprops] = prop; - elem->store_prop[elem->nprops] = OTHER_PROP; - elem->nprops++; - } - - /* save other info about other properties */ - elem->other_size = other->size; - elem->other_offset = offset; -} - - -/****************************************************************************** - State how many of a given element will be written. - - Entry: - plyfile - file identifier - elem_name - name of element that information is being specified about - nelems - number of elements of this type to be written -******************************************************************************/ - -void ply_element_count( - PlyFile *plyfile, - char *elem_name, - int nelems - ) -{ - PlyElement *elem; - - /* look for appropriate element */ - elem = find_element(plyfile, elem_name); - if (elem == NULL) { - fprintf(stderr, "ply_element_count: can't find element '%s'\n", elem_name); - exit(-1); - } - - elem->num = nelems; -} - - -/****************************************************************************** - Signal that we've described everything a PLY file's header and that the - header should be written to the file. - - Entry: - plyfile - file identifier -******************************************************************************/ - -void ply_header_complete(PlyFile *plyfile) -{ - int i, j; - FILE *fp = plyfile->fp; - PlyElement *elem; - PlyProperty *prop; - - fprintf(fp, "ply\n"); - - switch (plyfile->file_type) { - case PLY_ASCII: - fprintf(fp, "format ascii 1.0\n"); - break; - case PLY_BINARY_BE: - fprintf(fp, "format binary_big_endian 1.0\n"); - break; - case PLY_BINARY_LE: - fprintf(fp, "format binary_little_endian 1.0\n"); - break; - default: - fprintf(stderr, "ply_header_complete: bad file type = %d\n", - plyfile->file_type); - exit(-1); - } - - /* write out the comments */ - - for (i = 0; i < plyfile->num_comments; i++) - fprintf(fp, "comment %s\n", plyfile->comments[i]); - - /* write out object information */ - - for (i = 0; i < plyfile->num_obj_info; i++) - fprintf(fp, "obj_info %s\n", plyfile->obj_info[i]); - - /* write out information about each element */ - - for (i = 0; i < plyfile->nelems; i++) { - - elem = plyfile->elems[i]; - fprintf(fp, "element %s %d\n", elem->name, elem->num); - - /* write out each property */ - for (j = 0; j < elem->nprops; j++) { - prop = elem->props[j]; - if (prop->is_list) { - fprintf(fp, "property list "); - write_scalar_type(fp, prop->count_external); - fprintf(fp, " "); - write_scalar_type(fp, prop->external_type); - fprintf(fp, " %s\n", prop->name); - } - else { - fprintf(fp, "property "); - write_scalar_type(fp, prop->external_type); - fprintf(fp, " %s\n", prop->name); - } - } - } - - fprintf(fp, "end_header\n"); -} - - -/****************************************************************************** - Specify which elements are going to be written. This should be called - before a call to the routine ply_put_element(). - - Entry: - plyfile - file identifier - elem_name - name of element we're talking about -******************************************************************************/ - -void ply_put_element_setup(PlyFile *plyfile, char *elem_name) -{ - PlyElement *elem; - - elem = find_element(plyfile, elem_name); - if (elem == NULL) { - fprintf(stderr, "ply_elements_setup: can't find element '%s'\n", elem_name); - exit(-1); - } - - plyfile->which_elem = elem; -} - - -/****************************************************************************** - Write an element to the file. This routine assumes that we're - writing the type of element specified in the last call to the routine - ply_put_element_setup(). - - Entry: - plyfile - file identifier - elem_ptr - pointer to the element -******************************************************************************/ - -void ply_put_element(PlyFile *plyfile, void *elem_ptr) -{ - int j, k; - FILE *fp = plyfile->fp; - PlyElement *elem; - PlyProperty *prop; - char *elem_data, *item; - char **item_ptr; - int list_count; - int item_size; - int int_val; - unsigned int uint_val; - double double_val; - char **other_ptr; - - elem = plyfile->which_elem; - elem_data = elem_ptr; - other_ptr = (char **) (((char *) elem_ptr) + elem->other_offset); - - /* write out either to an ascii or binary file */ - - if (plyfile->file_type == PLY_ASCII) { - - /* write an ascii file */ - - /* write out each property of the element */ - for (j = 0; j < elem->nprops; j++) { - prop = elem->props[j]; - if (elem->store_prop[j] == OTHER_PROP) - elem_data = *other_ptr; - else - elem_data = elem_ptr; - if (prop->is_list) { - item = elem_data + prop->count_offset; - get_stored_item((void *) item, prop->count_internal, - &int_val, &uint_val, &double_val); - write_ascii_item(fp, int_val, uint_val, double_val, - prop->count_external); - list_count = uint_val; - item_ptr = (char **) (elem_data + prop->offset); - item = item_ptr[0]; - item_size = ply_type_size[prop->internal_type]; - for (k = 0; k < list_count; k++) { - get_stored_item((void *) item, prop->internal_type, - &int_val, &uint_val, &double_val); - write_ascii_item(fp, int_val, uint_val, double_val, - prop->external_type); - item += item_size; - } - } - else { - item = elem_data + prop->offset; - get_stored_item((void *) item, prop->internal_type, - &int_val, &uint_val, &double_val); - write_ascii_item(fp, int_val, uint_val, double_val, - prop->external_type); - } - } - - fprintf(fp, "\n"); - } - else { - - /* write a binary file */ - - /* write out each property of the element */ - for (j = 0; j < elem->nprops; j++) { - prop = elem->props[j]; - if (elem->store_prop[j] == OTHER_PROP) - elem_data = *other_ptr; - else - elem_data = elem_ptr; - if (prop->is_list) { - item = elem_data + prop->count_offset; - item_size = ply_type_size[prop->count_internal]; - get_stored_item((void *) item, prop->count_internal, - &int_val, &uint_val, &double_val); - write_binary_item(fp, int_val, uint_val, double_val, - prop->count_external); - list_count = uint_val; - item_ptr = (char **) (elem_data + prop->offset); - item = item_ptr[0]; - item_size = ply_type_size[prop->internal_type]; - for (k = 0; k < list_count; k++) { - get_stored_item((void *) item, prop->internal_type, - &int_val, &uint_val, &double_val); - write_binary_item(fp, int_val, uint_val, double_val, - prop->external_type); - item += item_size; - } - } - else { - item = elem_data + prop->offset; - item_size = ply_type_size[prop->internal_type]; - get_stored_item((void *) item, prop->internal_type, - &int_val, &uint_val, &double_val); - write_binary_item(fp, int_val, uint_val, double_val, - prop->external_type); - } - } - - } -} - - -/****************************************************************************** - Specify a comment that will be written in the header. - - Entry: - plyfile - file identifier - comment - the comment to be written -******************************************************************************/ - -void ply_put_comment(PlyFile *plyfile, char *comment) -{ - /* (re)allocate space for new comment */ - if (plyfile->num_comments == 0) - plyfile->comments = (char **) myalloc(sizeof(char *)); - else - plyfile->comments = (char **) realloc(plyfile->comments, - sizeof(char *) * (plyfile->num_comments + 1)); - - /* add comment to list */ - plyfile->comments[plyfile->num_comments] = strdup(comment); - plyfile->num_comments++; -} - - -/****************************************************************************** - Specify a piece of object information (arbitrary text) that will be written - in the header. - - Entry: - plyfile - file identifier - obj_info - the text information to be written -******************************************************************************/ - -void ply_put_obj_info(PlyFile *plyfile, char *obj_info) -{ - /* (re)allocate space for new info */ - if (plyfile->num_obj_info == 0) - plyfile->obj_info = (char **) myalloc(sizeof(char *)); - else - plyfile->obj_info = (char **) realloc(plyfile->obj_info, - sizeof(char *) * (plyfile->num_obj_info + 1)); - - /* add info to list */ - plyfile->obj_info[plyfile->num_obj_info] = strdup(obj_info); - plyfile->num_obj_info++; -} - - - - - - - -/*************/ -/* Reading */ -/*************/ - - - -/****************************************************************************** - Given a file pointer, get ready to read PLY data from the file. - - Entry: - fp - the given file pointer - - Exit: - nelems - number of elements in object - elem_names - list of element names - returns a pointer to a PlyFile, used to refer to this file, or NULL if error -******************************************************************************/ - -PlyFile *ply_read(FILE *fp, int *nelems, char ***elem_names) -{ - int i, j; - PlyFile *plyfile; - int nwords; - char **words; - int found_format = 0; - char **elist; - PlyElement *elem; - char *orig_line; - - /* check for NULL file pointer */ - if (fp == NULL) - return (NULL); - - /* create record for this object */ - - plyfile = (PlyFile *) myalloc(sizeof(PlyFile)); - plyfile->nelems = 0; - plyfile->comments = NULL; - plyfile->num_comments = 0; - plyfile->obj_info = NULL; - plyfile->num_obj_info = 0; - plyfile->fp = fp; - plyfile->other_elems = NULL; - - /* read and parse the file's header */ - - words = get_words(plyfile->fp, &nwords, &orig_line); - if (!words || !equal_strings(words[0], "ply")) - return (NULL); - - while (words) { - - /* parse words */ - - if (equal_strings(words[0], "format")) { - if (nwords != 3) - return (NULL); - if (equal_strings(words[1], "ascii")) - plyfile->file_type = PLY_ASCII; - else if (equal_strings(words[1], "binary_big_endian")) - plyfile->file_type = PLY_BINARY_BE; - else if (equal_strings(words[1], "binary_little_endian")) - plyfile->file_type = PLY_BINARY_LE; - else - return (NULL); - plyfile->version = (float)atof(words[2]); - found_format = 1; - } - else if (equal_strings(words[0], "element")) - add_element(plyfile, words); - else if (equal_strings(words[0], "property")) - add_property(plyfile, words); - else if (equal_strings(words[0], "comment")) - add_comment(plyfile, orig_line); - else if (equal_strings(words[0], "obj_info")) - add_obj_info(plyfile, orig_line); - else if (equal_strings(words[0], "end_header")) - break; - - /* free up words space */ - free(words); - - words = get_words(plyfile->fp, &nwords, &orig_line); - } - - /* create tags for each property of each element, to be used */ - /* later to say whether or not to store each property for the user */ - - for (i = 0; i < plyfile->nelems; i++) { - elem = plyfile->elems[i]; - elem->store_prop = (char *) myalloc(sizeof(char) * elem->nprops); - for (j = 0; j < elem->nprops; j++) - elem->store_prop[j] = DONT_STORE_PROP; - elem->other_offset = NO_OTHER_PROPS; /* no "other" props by default */ - } - - /* set return values about the elements */ - - elist = (char **) myalloc(sizeof(char *) * plyfile->nelems); - for (i = 0; i < plyfile->nelems; i++) - elist[i] = strdup(plyfile->elems[i]->name); - - *elem_names = elist; - *nelems = plyfile->nelems; - - /* return a pointer to the file's information */ - - return (plyfile); -} - - -/****************************************************************************** - Open a polygon file for reading. - - Entry: - filename - name of file to read from - - Exit: - nelems - number of elements in object - elem_names - list of element names - file_type - file type, either ascii or binary - version - version number of PLY file - returns a file identifier, used to refer to this file, or NULL if error -******************************************************************************/ - -PlyFile *ply_open_for_reading( - char *filename, - int *nelems, - char ***elem_names, - int *file_type, - float *version - ) -{ - FILE *fp; - PlyFile *plyfile; - char *name; - - /* tack on the extension .ply, if necessary */ - - name = (char *) myalloc(sizeof(char) * (strlen(filename) + 5)); - strcpy(name, filename); - if (strlen(name) < 4 || - strcmp(name + strlen(name) - 4, ".ply") != 0) - strcat(name, ".ply"); - - /* open the file for reading */ - - fp = fopen(name, "r"); - if (fp == NULL) - return (NULL); - - /* create the PlyFile data structure */ - - plyfile = ply_read(fp, nelems, elem_names); - - /* determine the file type and version */ - - *file_type = plyfile->file_type; - *version = plyfile->version; - - /* return a pointer to the file's information */ - - return (plyfile); -} - - -/****************************************************************************** - Get information about a particular element. - - Entry: - plyfile - file identifier - elem_name - name of element to get information about - - Exit: - nelems - number of elements of this type in the file - nprops - number of properties - returns a list of properties, or NULL if the file doesn't contain that elem -******************************************************************************/ - -PlyProperty **ply_get_element_description( - PlyFile *plyfile, - char *elem_name, - int *nelems, - int *nprops - ) -{ - int i; - PlyElement *elem; - PlyProperty *prop; - PlyProperty **prop_list; - - /* find information about the element */ - elem = find_element(plyfile, elem_name); - if (elem == NULL) - return (NULL); - - *nelems = elem->num; - *nprops = elem->nprops; - - /* make a copy of the element's property list */ - prop_list = (PlyProperty **) myalloc(sizeof(PlyProperty *) * elem->nprops); - for (i = 0; i < elem->nprops; i++) { - prop = (PlyProperty *) myalloc(sizeof(PlyProperty)); - copy_property(prop, elem->props[i]); - prop_list[i] = prop; - } - - /* return this duplicate property list */ - return (prop_list); -} - - -/****************************************************************************** - Specify which properties of an element are to be returned. This should be - called before a call to the routine ply_get_element(). - - Entry: - plyfile - file identifier - elem_name - which element we're talking about - nprops - number of properties - prop_list - list of properties -******************************************************************************/ - -void ply_get_element_setup( - PlyFile *plyfile, - char *elem_name, - int nprops, - PlyProperty *prop_list - ) -{ - int i; - PlyElement *elem; - PlyProperty *prop; - int index; - - /* find information about the element */ - elem = find_element(plyfile, elem_name); - plyfile->which_elem = elem; - - /* deposit the property information into the element's description */ - for (i = 0; i < nprops; i++) { - - /* look for actual property */ - prop = find_property(elem, prop_list[i].name, &index); - if (prop == NULL) { - fprintf(stderr, "Warning: Can't find property '%s' in element '%s'\n", - prop_list[i].name, elem_name); - continue; - } - - /* store its description */ - prop->internal_type = prop_list[i].internal_type; - prop->offset = prop_list[i].offset; - prop->count_internal = prop_list[i].count_internal; - prop->count_offset = prop_list[i].count_offset; - - /* specify that the user wants this property */ - elem->store_prop[index] = STORE_PROP; - } -} - - -/****************************************************************************** - Specify a property of an element that is to be returned. This should be - called (usually multiple times) before a call to the routine ply_get_element(). - This routine should be used in preference to the less flexible old routine - called ply_get_element_setup(). - - Entry: - plyfile - file identifier - elem_name - which element we're talking about - prop - property to add to those that will be returned -******************************************************************************/ - -void ply_get_property( - PlyFile *plyfile, - char *elem_name, - PlyProperty *prop - ) -{ - PlyElement *elem; - PlyProperty *prop_ptr; - int index; - - /* find information about the element */ - elem = find_element(plyfile, elem_name); - plyfile->which_elem = elem; - - /* deposit the property information into the element's description */ - - prop_ptr = find_property(elem, prop->name, &index); - if (prop_ptr == NULL) { - fprintf(stderr, "Warning: Can't find property '%s' in element '%s'\n", - prop->name, elem_name); - return; - } - prop_ptr->internal_type = prop->internal_type; - prop_ptr->offset = prop->offset; - prop_ptr->count_internal = prop->count_internal; - prop_ptr->count_offset = prop->count_offset; - - /* specify that the user wants this property */ - elem->store_prop[index] = STORE_PROP; -} - - -/****************************************************************************** - Read one element from the file. This routine assumes that we're reading - the type of element specified in the last call to the routine - ply_get_element_setup(). - - Entry: - plyfile - file identifier - elem_ptr - pointer to location where the element information should be put -******************************************************************************/ - -void ply_get_element(PlyFile *plyfile, void *elem_ptr) -{ - if (plyfile->file_type == PLY_ASCII) - ascii_get_element(plyfile, (char *) elem_ptr); - else - binary_get_element(plyfile, (char *) elem_ptr); -} - - -/****************************************************************************** - Extract the comments from the header information of a PLY file. - - Entry: - plyfile - file identifier - - Exit: - num_comments - number of comments returned - returns a pointer to a list of comments -******************************************************************************/ - -char **ply_get_comments(PlyFile *plyfile, int *num_comments) -{ - *num_comments = plyfile->num_comments; - return (plyfile->comments); -} - - -/****************************************************************************** - Extract the object information (arbitrary text) from the header information - of a PLY file. - - Entry: - plyfile - file identifier - - Exit: - num_obj_info - number of lines of text information returned - returns a pointer to a list of object info lines -******************************************************************************/ - -char **ply_get_obj_info(PlyFile *plyfile, int *num_obj_info) -{ - *num_obj_info = plyfile->num_obj_info; - return (plyfile->obj_info); -} - - -/****************************************************************************** - Make ready for "other" properties of an element-- those properties that - the user has not explicitly asked for, but that are to be stashed away - in a special structure to be carried along with the element's other - information. - - Entry: - plyfile - file identifier - elem - element for which we want to save away other properties -******************************************************************************/ - -void setup_other_props(PlyElement *elem) -{ - int i; - PlyProperty *prop; - int size = 0; - int type_size; - - /* Examine each property in decreasing order of size. */ - /* We do this so that all data types will be aligned by */ - /* word, half-word, or whatever within the structure. */ - - for (type_size = 8; type_size > 0; type_size /= 2) { - - /* add up the space taken by each property, and save this information */ - /* away in the property descriptor */ - - for (i = 0; i < elem->nprops; i++) { - - /* don't bother with properties we've been asked to store explicitly */ - if (elem->store_prop[i]) - continue; - - prop = elem->props[i]; - - /* internal types will be same as external */ - prop->internal_type = prop->external_type; - prop->count_internal = prop->count_external; - - /* check list case */ - if (prop->is_list) { - - /* pointer to list */ - if (type_size == sizeof(void *)) { - prop->offset = size; - size += sizeof(void *); /* always use size of a pointer here */ - } - - /* count of number of list elements */ - if (type_size == ply_type_size[prop->count_external]) { - prop->count_offset = size; - size += ply_type_size[prop->count_external]; - } - } - /* not list */ - else if (type_size == ply_type_size[prop->external_type]) { - prop->offset = size; - size += ply_type_size[prop->external_type]; - } - } - - } - - /* save the size for the other_props structure */ - elem->other_size = size; -} - - -/****************************************************************************** - Specify that we want the "other" properties of an element to be tucked - away within the user's structure. The user needn't be concerned for how - these properties are stored. - - Entry: - plyfile - file identifier - elem_name - name of element that we want to store other_props in - offset - offset to where other_props will be stored inside user's structure - - Exit: - returns pointer to structure containing description of other_props -******************************************************************************/ - -PlyOtherProp *ply_get_other_properties( - PlyFile *plyfile, - char *elem_name, - int offset - ) -{ - int i; - PlyElement *elem; - PlyOtherProp *other; - PlyProperty *prop; - int nprops; - - /* find information about the element */ - elem = find_element(plyfile, elem_name); - if (elem == NULL) { - fprintf(stderr, "ply_get_other_properties: Can't find element '%s'\n", - elem_name); - return (NULL); - } - - /* remember that this is the "current" element */ - plyfile->which_elem = elem; - - /* save the offset to where to store the other_props */ - elem->other_offset = offset; - - /* place the appropriate pointers, etc. in the element's property list */ - setup_other_props(elem); - - /* create structure for describing other_props */ - other = (PlyOtherProp *) myalloc(sizeof(PlyOtherProp)); - other->name = strdup(elem_name); -#if 0 - if (elem->other_offset == NO_OTHER_PROPS) { - other->size = 0; - other->props = NULL; - other->nprops = 0; - return (other); - } -#endif - other->size = elem->other_size; - other->props = (PlyProperty **) myalloc(sizeof(PlyProperty) * elem->nprops); - - /* save descriptions of each "other" property */ - nprops = 0; - for (i = 0; i < elem->nprops; i++) { - if (elem->store_prop[i]) - continue; - prop = (PlyProperty *) myalloc(sizeof(PlyProperty)); - copy_property(prop, elem->props[i]); - other->props[nprops] = prop; - nprops++; - } - other->nprops = nprops; - -#if 1 - /* set other_offset pointer appropriately if there are NO other properties */ - if (other->nprops == 0) { - elem->other_offset = NO_OTHER_PROPS; - } -#endif - - /* return structure */ - return (other); -} - - - - -/*************************/ -/* Other Element Stuff */ -/*************************/ - - - - -/****************************************************************************** - Grab all the data for an element that a user does not want to explicitly - read in. - - Entry: - plyfile - pointer to file - elem_name - name of element whose data is to be read in - elem_count - number of instances of this element stored in the file - - Exit: - returns pointer to ALL the "other" element data for this PLY file -******************************************************************************/ - -PlyOtherElems *ply_get_other_element( - PlyFile *plyfile, - char *elem_name, - int elem_count - ) -{ - int i; - PlyElement *elem; - PlyOtherElems *other_elems; - OtherElem *other; - - /* look for appropriate element */ - elem = find_element(plyfile, elem_name); - if (elem == NULL) { - fprintf(stderr, - "ply_get_other_element: can't find element '%s'\n", elem_name); - exit(-1); - } - - /* create room for the new "other" element, initializing the */ - /* other data structure if necessary */ - - if (plyfile->other_elems == NULL) { - plyfile->other_elems = (PlyOtherElems *) myalloc(sizeof(PlyOtherElems)); - other_elems = plyfile->other_elems; - other_elems->other_list = (OtherElem *) myalloc(sizeof(OtherElem)); - other = &(other_elems->other_list[0]); - other_elems->num_elems = 1; - } - else { - other_elems = plyfile->other_elems; - other_elems->other_list = (OtherElem *) realloc(other_elems->other_list, - sizeof(OtherElem) * other_elems->num_elems + 1); - other = &(other_elems->other_list[other_elems->num_elems]); - other_elems->num_elems++; - } - - /* count of element instances in file */ - other->elem_count = elem_count; - - /* save name of element */ - other->elem_name = strdup(elem_name); - - /* create a list to hold all the current elements */ - other->other_data = (OtherData **) - malloc(sizeof(OtherData *) * other->elem_count); - - /* set up for getting elements */ - other->other_props = ply_get_other_properties(plyfile, elem_name, - offsetof(OtherData, other_props)); - - /* grab all these elements */ - for (i = 0; i < other->elem_count; i++) { - /* grab and element from the file */ - other->other_data[i] = (OtherData *) malloc(sizeof(OtherData)); - ply_get_element(plyfile, (void *) other->other_data[i]); - } - - /* return pointer to the other elements data */ - return (other_elems); -} - - -/****************************************************************************** - Pass along a pointer to "other" elements that we want to save in a given - PLY file. These other elements were presumably read from another PLY file. - - Entry: - plyfile - file pointer in which to store this other element info - other_elems - info about other elements that we want to store -******************************************************************************/ - -void ply_describe_other_elements( - PlyFile *plyfile, - PlyOtherElems *other_elems - ) -{ - int i; - OtherElem *other; - - /* ignore this call if there is no other element */ - if (other_elems == NULL) - return; - - /* save pointer to this information */ - plyfile->other_elems = other_elems; - - /* describe the other properties of this element */ - - for (i = 0; i < other_elems->num_elems; i++) { - other = &(other_elems->other_list[i]); - ply_element_count(plyfile, other->elem_name, other->elem_count); - ply_describe_other_properties(plyfile, other->other_props, - offsetof(OtherData, other_props)); - } -} - - -/****************************************************************************** - Write out the "other" elements specified for this PLY file. - - Entry: - plyfile - pointer to PLY file to write out other elements for -******************************************************************************/ - -void ply_put_other_elements(PlyFile *plyfile) -{ - int i, j; - OtherElem *other; - - /* make sure we have other elements to write */ - if (plyfile->other_elems == NULL) - return; - - /* write out the data for each "other" element */ - - for (i = 0; i < plyfile->other_elems->num_elems; i++) { - - other = &(plyfile->other_elems->other_list[i]); - ply_put_element_setup(plyfile, other->elem_name); - - /* write out each instance of the current element */ - for (j = 0; j < other->elem_count; j++) - ply_put_element(plyfile, (void *) other->other_data[j]); - } -} - - -/****************************************************************************** - Free up storage used by an "other" elements data structure. - - Entry: - other_elems - data structure to free up -******************************************************************************/ - - - - -/*******************/ -/* Miscellaneous */ -/*******************/ - - - -/****************************************************************************** - Close a PLY file. - - Entry: - plyfile - identifier of file to close -******************************************************************************/ - -void ply_close(PlyFile *plyfile) -{ - fclose(plyfile->fp); - - /* free up memory associated with the PLY file */ - free(plyfile); -} - - -/****************************************************************************** - Get version number and file type of a PlyFile. - - Entry: - ply - pointer to PLY file - - Exit: - version - version of the file - file_type - PLY_ASCII, PLY_BINARY_BE, or PLY_BINARY_LE -******************************************************************************/ - -void ply_get_info(PlyFile *ply, float *version, int *file_type) -{ - if (ply == NULL) - return; - - *version = ply->version; - *file_type = ply->file_type; -} - - -/****************************************************************************** - Compare two strings. Returns 1 if they are the same, 0 if not. -******************************************************************************/ - -int equal_strings(char *s1, char *s2) -{ - - while (*s1 && *s2) - if (*s1++ != *s2++) - return (0); - - if (*s1 != *s2) - return (0); - else - return (1); -} - - -/****************************************************************************** - Find an element from the element list of a given PLY object. - - Entry: - plyfile - file id for PLY file - element - name of element we're looking for - - Exit: - returns the element, or NULL if not found -******************************************************************************/ - -PlyElement *find_element(PlyFile *plyfile, char *element) -{ - int i; - - for (i = 0; i < plyfile->nelems; i++) - if (equal_strings(element, plyfile->elems[i]->name)) - return (plyfile->elems[i]); - - return (NULL); -} - - -/****************************************************************************** - Find a property in the list of properties of a given element. - - Entry: - elem - pointer to element in which we want to find the property - prop_name - name of property to find - - Exit: - index - index to position in list - returns a pointer to the property, or NULL if not found -******************************************************************************/ - -PlyProperty *find_property(PlyElement *elem, char *prop_name, int *index) -{ - int i; - - for (i = 0; i < elem->nprops; i++) - if (equal_strings(prop_name, elem->props[i]->name)) { - *index = i; - return (elem->props[i]); - } - - *index = -1; - return (NULL); -} - - -/****************************************************************************** - Read an element from an ascii file. - - Entry: - plyfile - file identifier - elem_ptr - pointer to element -******************************************************************************/ - -void ascii_get_element(PlyFile *plyfile, char *elem_ptr) -{ - int j, k; - PlyElement *elem; - PlyProperty *prop; - char **words; - int nwords; - int which_word; - char *elem_data, *item; - char *item_ptr; - int item_size; - int int_val; - unsigned int uint_val; - double double_val; - int list_count; - int store_it; - char **store_array; - char *orig_line; - char *other_data; - int other_flag; - - other_flag = 0; - other_data = NULL; - item = NULL; - item_size = 0; - - /* the kind of element we're reading currently */ - elem = plyfile->which_elem; - - /* do we need to setup for other_props? */ - - if (elem->other_offset != NO_OTHER_PROPS) { - char **ptr; - other_flag = 1; - /* make room for other_props */ - other_data = (char *) myalloc(elem->other_size); - /* store pointer in user's structure to the other_props */ - ptr = (char **) (elem_ptr + elem->other_offset); - *ptr = other_data; - } - else { - other_flag = 0; - other_data = NULL; - item = NULL; - item_size = 0; - } - - /* read in the element */ - - words = get_words(plyfile->fp, &nwords, &orig_line); - if (words == NULL) { - fprintf(stderr, "ply_get_element: unexpected end of file\n"); - exit(-1); - } - - which_word = 0; - - for (j = 0; j < elem->nprops; j++) { - - prop = elem->props[j]; - store_it = (elem->store_prop[j] | other_flag); - - /* store either in the user's structure or in other_props */ - if (elem->store_prop[j]) - elem_data = elem_ptr; - else - elem_data = other_data; - - if (prop->is_list) { /* a list */ - - /* get and store the number of items in the list */ - get_ascii_item(words[which_word++], prop->count_external, - &int_val, &uint_val, &double_val); - if (store_it) { - item = elem_data + prop->count_offset; - store_item(item, prop->count_internal, int_val, uint_val, double_val); - } - - /* allocate space for an array of items and store a ptr to the array */ - list_count = int_val; - item_size = ply_type_size[prop->internal_type]; - store_array = (char **) (elem_data + prop->offset); - - if (list_count == 0) { - if (store_it) - *store_array = NULL; - } - else { - if (store_it) { - item_ptr = (char *) myalloc(sizeof(char) * item_size * list_count); - item = item_ptr; - *store_array = item_ptr; - } - - /* read items and store them into the array */ - for (k = 0; k < list_count; k++) { - get_ascii_item(words[which_word++], prop->external_type, - &int_val, &uint_val, &double_val); - if (store_it) { - store_item(item, prop->internal_type, - int_val, uint_val, double_val); - item += item_size; - } - } - } - - } - else { /* not a list */ - get_ascii_item(words[which_word++], prop->external_type, - &int_val, &uint_val, &double_val); - if (store_it) { - item = elem_data + prop->offset; - store_item(item, prop->internal_type, int_val, uint_val, double_val); - } - } - - } - - free(words); -} - - -/****************************************************************************** - Read an element from a binary file. - - Entry: - plyfile - file identifier - elem_ptr - pointer to an element -******************************************************************************/ - -void binary_get_element(PlyFile *plyfile, char *elem_ptr) -{ - int j, k; - PlyElement *elem; - PlyProperty *prop; - FILE *fp = plyfile->fp; - char *elem_data, *item; - char *item_ptr; - int item_size; - int int_val; - unsigned int uint_val; - double double_val; - int list_count; - int store_it; - char **store_array; - char *other_data; - int other_flag; - - - other_flag = 0; - other_data = NULL; - item = NULL; - item_size = 0; - - /* the kind of element we're reading currently */ - elem = plyfile->which_elem; - - /* do we need to setup for other_props? */ - - if (elem->other_offset != NO_OTHER_PROPS) { - char **ptr; - other_flag = 1; - /* make room for other_props */ - other_data = (char *) myalloc(elem->other_size); - /* store pointer in user's structure to the other_props */ - ptr = (char **) (elem_ptr + elem->other_offset); - *ptr = other_data; - } - else { - other_flag = 0; - other_data = NULL; - item = NULL; - item_size = 0; - } - /* read in a number of elements */ - - for (j = 0; j < elem->nprops; j++) { - - prop = elem->props[j]; - store_it = (elem->store_prop[j] | other_flag); - - /* store either in the user's structure or in other_props */ - if (elem->store_prop[j]) - elem_data = elem_ptr; - else - elem_data = other_data; - - if (prop->is_list) { /* a list */ - - /* get and store the number of items in the list */ - get_binary_item(fp, prop->count_external, - &int_val, &uint_val, &double_val); - if (store_it) { - item = elem_data + prop->count_offset; - store_item(item, prop->count_internal, int_val, uint_val, double_val); - } - - /* allocate space for an array of items and store a ptr to the array */ - list_count = int_val; - /* The "if" was added by Afra Zomorodian 8/22/95 - * so that zipper won't crash reading plies that have additional - * properties. - */ - if (store_it) { - item_size = ply_type_size[prop->internal_type]; - } - store_array = (char **) (elem_data + prop->offset); - if (list_count == 0) { - if (store_it) - *store_array = NULL; - } - else { - if (store_it) { - item_ptr = (char *) myalloc(sizeof(char) * item_size * list_count); - item = item_ptr; - *store_array = item_ptr; - } - - /* read items and store them into the array */ - for (k = 0; k < list_count; k++) { - get_binary_item(fp, prop->external_type, - &int_val, &uint_val, &double_val); - if (store_it) { - store_item(item, prop->internal_type, - int_val, uint_val, double_val); - item += item_size; - } - } - } - - } - else { /* not a list */ - get_binary_item(fp, prop->external_type, - &int_val, &uint_val, &double_val); - if (store_it) { - item = elem_data + prop->offset; - store_item(item, prop->internal_type, int_val, uint_val, double_val); - } - } - - } -} - - -/****************************************************************************** - Write to a file the word that represents a PLY data type. - - Entry: - fp - file pointer - code - code for type -******************************************************************************/ - -void write_scalar_type(FILE *fp, int code) -{ - /* make sure this is a valid code */ - - if (code <= PLY_START_TYPE || code >= PLY_END_TYPE) { - fprintf(stderr, "write_scalar_type: bad data code = %d\n", code); - exit(-1); - } - - /* write the code to a file */ - - fprintf(fp, "%s", type_names[code]); -} - - -/****************************************************************************** - Get a text line from a file and break it up into words. - - IMPORTANT: The calling routine call "free" on the returned pointer once - finished with it. - - Entry: - fp - file to read from - - Exit: - nwords - number of words returned - orig_line - the original line of characters - returns a list of words from the line, or NULL if end-of-file -******************************************************************************/ - -char **get_words(FILE *fp, int *nwords, char **orig_line) -{ -#define BIG_STRING 4096 - static char str[BIG_STRING]; - static char str_copy[BIG_STRING]; - char **words; - int max_words = 10; - int num_words = 0; - char *ptr, *ptr2; - char *result; - - words = (char **) myalloc(sizeof(char *) * max_words); - - /* read in a line */ - result = fgets(str, BIG_STRING, fp); - if (result == NULL) { - *nwords = 0; - *orig_line = NULL; - return (NULL); - } - - /* convert line-feed and tabs into spaces */ - /* (this guarentees that there will be a space before the */ - /* null character at the end of the string) */ - - str[BIG_STRING - 2] = ' '; - str[BIG_STRING - 1] = '\0'; - - for (ptr = str, ptr2 = str_copy; *ptr != '\0'; ptr++, ptr2++) { - *ptr2 = *ptr; - if (*ptr == '\t') { - *ptr = ' '; - *ptr2 = ' '; - } - else if (*ptr == '\n') { - *ptr = ' '; - *ptr2 = '\0'; - break; - } - } - - /* find the words in the line */ - - ptr = str; - while (*ptr != '\0') { - - /* jump over leading spaces */ - while (*ptr == ' ') - ptr++; - - /* break if we reach the end */ - if (*ptr == '\0') - break; - - /* save pointer to beginning of word */ - if (num_words >= max_words) { - max_words += 10; - words = (char **) realloc(words, sizeof(char *) * max_words); - } - words[num_words++] = ptr; - - /* jump over non-spaces */ - while (*ptr != ' ') - ptr++; - - /* place a null character here to mark the end of the word */ - *ptr++ = '\0'; - } - - /* return the list of words */ - *nwords = num_words; - *orig_line = str_copy; - return (words); -} - - -/****************************************************************************** - Return the value of an item, given a pointer to it and its type. - - Entry: - item - pointer to item - type - data type that "item" points to - - Exit: - returns a double-precision float that contains the value of the item -******************************************************************************/ - -double get_item_value(char *item, int type) -{ - unsigned char *puchar; - char *pchar; - short int *pshort; - unsigned short int *pushort; - int *pint; - unsigned int *puint; - float *pfloat; - double *pdouble; - int int_value; - unsigned int uint_value; - double double_value; - - switch (type) { - case PLY_CHAR: - pchar = (char *) item; - int_value = *pchar; - return ((double) int_value); - case PLY_UCHAR: - puchar = (unsigned char *) item; - int_value = *puchar; - return ((double) int_value); - case PLY_SHORT: - pshort = (short int *) item; - int_value = *pshort; - return ((double) int_value); - case PLY_USHORT: - pushort = (unsigned short int *) item; - int_value = *pushort; - return ((double) int_value); - case PLY_INT: - pint = (int *) item; - int_value = *pint; - return ((double) int_value); - case PLY_UINT: - puint = (unsigned int *) item; - uint_value = *puint; - return ((double) uint_value); - case PLY_FLOAT: - pfloat = (float *) item; - double_value = *pfloat; - return (double_value); - case PLY_DOUBLE: - pdouble = (double *) item; - double_value = *pdouble; - return (double_value); - default: - fprintf(stderr, "get_item_value: bad type = %d\n", type); - exit(-1); - } -} - - -/****************************************************************************** - Write out an item to a file as raw binary bytes. - - Entry: - fp - file to write to - int_val - integer version of item - uint_val - unsigned integer version of item - double_val - double-precision float version of item - type - data type to write out -******************************************************************************/ - -void write_binary_item( - FILE *fp, - int int_val, - unsigned int uint_val, - double double_val, - int type - ) -{ - unsigned char uchar_val; - char char_val; - unsigned short ushort_val; - short short_val; - float float_val; - - switch (type) { - case PLY_CHAR: - char_val = (char)int_val; - fwrite(&char_val, 1, 1, fp); - break; - case PLY_SHORT: - short_val = (short)int_val; - fwrite(&short_val, 2, 1, fp); - break; - case PLY_INT: - fwrite(&int_val, 4, 1, fp); - break; - case PLY_UCHAR: - uchar_val = (unsigned char) uint_val; - fwrite(&uchar_val, 1, 1, fp); - break; - case PLY_USHORT: - ushort_val = (unsigned short)uint_val; - fwrite(&ushort_val, 2, 1, fp); - break; - case PLY_UINT: - fwrite(&uint_val, 4, 1, fp); - break; - case PLY_FLOAT: - float_val = (float) double_val; - fwrite(&float_val, 4, 1, fp); - break; - case PLY_DOUBLE: - fwrite(&double_val, 8, 1, fp); - break; - default: - fprintf(stderr, "write_binary_item: bad type = %d\n", type); - exit(-1); - } -} - - -/****************************************************************************** - Write out an item to a file as ascii characters. - - Entry: - fp - file to write to - int_val - integer version of item - uint_val - unsigned integer version of item - double_val - double-precision float version of item - type - data type to write out -******************************************************************************/ - -void write_ascii_item( - FILE *fp, - int int_val, - unsigned int uint_val, - double double_val, - int type - ) -{ - switch (type) { - case PLY_CHAR: - case PLY_SHORT: - case PLY_INT: - fprintf(fp, "%d ", int_val); - break; - case PLY_UCHAR: - case PLY_USHORT: - case PLY_UINT: - fprintf(fp, "%u ", uint_val); - break; - case PLY_FLOAT: - case PLY_DOUBLE: - fprintf(fp, "%g ", double_val); - break; - default: - fprintf(stderr, "write_ascii_item: bad type = %d\n", type); - exit(-1); - } -} - - -/****************************************************************************** - Write out an item to a file as ascii characters. - - Entry: - fp - file to write to - item - pointer to item to write - type - data type that "item" points to - - Exit: - returns a double-precision float that contains the value of the written item -******************************************************************************/ - -double old_write_ascii_item(FILE *fp, char *item, int type) -{ - unsigned char *puchar; - char *pchar; - short int *pshort; - unsigned short int *pushort; - int *pint; - unsigned int *puint; - float *pfloat; - double *pdouble; - int int_value; - unsigned int uint_value; - double double_value; - - switch (type) { - case PLY_CHAR: - pchar = (char *) item; - int_value = *pchar; - fprintf(fp, "%d ", int_value); - return ((double) int_value); - case PLY_UCHAR: - puchar = (unsigned char *) item; - int_value = *puchar; - fprintf(fp, "%d ", int_value); - return ((double) int_value); - case PLY_SHORT: - pshort = (short int *) item; - int_value = *pshort; - fprintf(fp, "%d ", int_value); - return ((double) int_value); - case PLY_USHORT: - pushort = (unsigned short int *) item; - int_value = *pushort; - fprintf(fp, "%d ", int_value); - return ((double) int_value); - case PLY_INT: - pint = (int *) item; - int_value = *pint; - fprintf(fp, "%d ", int_value); - return ((double) int_value); - case PLY_UINT: - puint = (unsigned int *) item; - uint_value = *puint; - fprintf(fp, "%u ", uint_value); - return ((double) uint_value); - case PLY_FLOAT: - pfloat = (float *) item; - double_value = *pfloat; - fprintf(fp, "%g ", double_value); - return (double_value); - case PLY_DOUBLE: - pdouble = (double *) item; - double_value = *pdouble; - fprintf(fp, "%g ", double_value); - return (double_value); - default: - fprintf(stderr, "old_write_ascii_item: bad type = %d\n", type); - exit(-1); - } -} - - -/****************************************************************************** - Get the value of an item that is in memory, and place the result - into an integer, an unsigned integer and a double. - - Entry: - ptr - pointer to the item - type - data type supposedly in the item - - Exit: - int_val - integer value - uint_val - unsigned integer value - double_val - double-precision floating point value -******************************************************************************/ - -void get_stored_item( - void *ptr, - int type, - int *int_val, - unsigned int *uint_val, - double *double_val - ) -{ - switch (type) { - case PLY_CHAR: - *int_val = *((char *) ptr); - *uint_val = *int_val; - *double_val = *int_val; - break; - case PLY_UCHAR: - *uint_val = *((unsigned char *) ptr); - *int_val = *uint_val; - *double_val = *uint_val; - break; - case PLY_SHORT: - *int_val = *((short int *) ptr); - *uint_val = *int_val; - *double_val = *int_val; - break; - case PLY_USHORT: - *uint_val = *((unsigned short int *) ptr); - *int_val = *uint_val; - *double_val = *uint_val; - break; - case PLY_INT: - *int_val = *((int *) ptr); - *uint_val = *int_val; - *double_val = *int_val; - break; - case PLY_UINT: - *uint_val = *((unsigned int *) ptr); - *int_val = *uint_val; - *double_val = *uint_val; - break; - case PLY_FLOAT: - *double_val = *((float *) ptr); - *int_val = (int)*double_val; - *uint_val = (unsigned int)*double_val; - break; - case PLY_DOUBLE: - *double_val = *((double *) ptr); - *int_val = (int)*double_val; - *uint_val = (unsigned int) *double_val; - break; - default: - fprintf(stderr, "get_stored_item: bad type = %d\n", type); - exit(-1); - } -} - - -/****************************************************************************** - Get the value of an item from a binary file, and place the result - into an integer, an unsigned integer and a double. - - Entry: - fp - file to get item from - type - data type supposedly in the word - - Exit: - int_val - integer value - uint_val - unsigned integer value - double_val - double-precision floating point value -******************************************************************************/ - -void get_binary_item( - FILE *fp, - int type, - int *int_val, - unsigned int *uint_val, - double *double_val - ) -{ - char c[8]; - void *ptr; - - ptr = (void *) c; - - switch (type) { - case PLY_CHAR: - fread(ptr, 1, 1, fp); - *int_val = *((char *) ptr); - *uint_val = *int_val; - *double_val = *int_val; - break; - case PLY_UCHAR: - fread(ptr, 1, 1, fp); - *uint_val = *((unsigned char *) ptr); - *int_val = *uint_val; - *double_val = *uint_val; - break; - case PLY_SHORT: - fread(ptr, 2, 1, fp); - *int_val = *((short int *) ptr); - *uint_val = *int_val; - *double_val = *int_val; - break; - case PLY_USHORT: - fread(ptr, 2, 1, fp); - *uint_val = *((unsigned short int *) ptr); - *int_val = *uint_val; - *double_val = *uint_val; - break; - case PLY_INT: - fread(ptr, 4, 1, fp); - *int_val = *((int *) ptr); - *uint_val = *int_val; - *double_val = *int_val; - break; - case PLY_UINT: - fread(ptr, 4, 1, fp); - *uint_val = *((unsigned int *) ptr); - *int_val = *uint_val; - *double_val = *uint_val; - break; - case PLY_FLOAT: - fread(ptr, 4, 1, fp); - *double_val = *((float *) ptr); - *int_val = (int)*double_val; - *uint_val = (unsigned int) *double_val; - break; - case PLY_DOUBLE: - fread(ptr, 8, 1, fp); - *double_val = *((double *) ptr); - *int_val = (int)*double_val; - *uint_val = (unsigned int)*double_val; - break; - default: - fprintf(stderr, "get_binary_item: bad type = %d\n", type); - exit(-1); - } -} - - -/****************************************************************************** - Extract the value of an item from an ascii word, and place the result - into an integer, an unsigned integer and a double. - - Entry: - word - word to extract value from - type - data type supposedly in the word - - Exit: - int_val - integer value - uint_val - unsigned integer value - double_val - double-precision floating point value -******************************************************************************/ - -void get_ascii_item( - char *word, - int type, - int *int_val, - unsigned int *uint_val, - double *double_val - ) -{ - switch (type) { - case PLY_CHAR: - case PLY_UCHAR: - case PLY_SHORT: - case PLY_USHORT: - case PLY_INT: - *int_val = atoi(word); - *uint_val = *int_val; - *double_val = *int_val; - break; - - case PLY_UINT: - *uint_val = strtoul(word, (char **) NULL, 10); - *int_val = *uint_val; - *double_val = *uint_val; - break; - - case PLY_FLOAT: - case PLY_DOUBLE: - *double_val = atof(word); - *int_val = (int) *double_val; - *uint_val = (unsigned int) *double_val; - break; - - default: - fprintf(stderr, "get_ascii_item: bad type = %d\n", type); - exit(-1); - } -} - - -/****************************************************************************** - Store a value into a place being pointed to, guided by a data type. - - Entry: - item - place to store value - type - data type - int_val - integer version of value - uint_val - unsigned integer version of value - double_val - double version of value - - Exit: - item - pointer to stored value -******************************************************************************/ - -void store_item( - char *item, - int type, - int int_val, - unsigned int uint_val, - double double_val - ) -{ - unsigned char *puchar; - short int *pshort; - unsigned short int *pushort; - int *pint; - unsigned int *puint; - float *pfloat; - double *pdouble; - - switch (type) { - case PLY_CHAR: - *item = (char) int_val; - break; - case PLY_UCHAR: - puchar = (unsigned char *) item; - *puchar = (unsigned char)uint_val; - break; - case PLY_SHORT: - pshort = (short *) item; - *pshort = (short)int_val; - break; - case PLY_USHORT: - pushort = (unsigned short *) item; - *pushort = (unsigned short)uint_val; - break; - case PLY_INT: - pint = (int *) item; - *pint = int_val; - break; - case PLY_UINT: - puint = (unsigned int *) item; - *puint = uint_val; - break; - case PLY_FLOAT: - pfloat = (float *) item; - *pfloat = (float)double_val; - break; - case PLY_DOUBLE: - pdouble = (double *) item; - *pdouble = double_val; - break; - default: - fprintf(stderr, "store_item: bad type = %d\n", type); - exit(-1); - } -} - - -/****************************************************************************** - Add an element to a PLY file descriptor. - - Entry: - plyfile - PLY file descriptor - words - list of words describing the element - nwords - number of words in the list -******************************************************************************/ - -void add_element(PlyFile *plyfile, char **words) -{ - PlyElement *elem; - - /* create the new element */ - elem = (PlyElement *) myalloc(sizeof(PlyElement)); - elem->name = strdup(words[1]); - elem->num = atoi(words[2]); - elem->nprops = 0; - - /* make room for new element in the object's list of elements */ - if (plyfile->nelems == 0) - plyfile->elems = (PlyElement **) myalloc(sizeof(PlyElement *)); - else - plyfile->elems = (PlyElement **) realloc(plyfile->elems, - sizeof(PlyElement *) * (plyfile->nelems + 1)); - - /* add the new element to the object's list */ - plyfile->elems[plyfile->nelems] = elem; - plyfile->nelems++; -} - - -/****************************************************************************** - Return the type of a property, given the name of the property. - - Entry: - name - name of property type - - Exit: - returns integer code for property, or 0 if not found -******************************************************************************/ - -int get_prop_type(char *type_name) -{ - int i; - - for (i = PLY_START_TYPE + 1; i < PLY_END_TYPE; i++) - if (equal_strings(type_name, type_names[i])) - return (i); - - /* if we get here, we didn't find the type */ - return (0); -} - - -/****************************************************************************** - Add a property to a PLY file descriptor. - - Entry: - plyfile - PLY file descriptor - words - list of words describing the property - nwords - number of words in the list -******************************************************************************/ - -void add_property(PlyFile *plyfile, char **words) -{ - PlyProperty *prop; - PlyElement *elem; - - /* create the new property */ - - prop = (PlyProperty *) myalloc(sizeof(PlyProperty)); - - if (equal_strings(words[1], "list")) { /* is a list */ - prop->count_external = get_prop_type(words[2]); - prop->external_type = get_prop_type(words[3]); - prop->name = strdup(words[4]); - prop->is_list = 1; - } - else { /* not a list */ - prop->external_type = get_prop_type(words[1]); - prop->name = strdup(words[2]); - prop->is_list = 0; - } - - /* add this property to the list of properties of the current element */ - - elem = plyfile->elems[plyfile->nelems - 1]; - - if (elem->nprops == 0) - elem->props = (PlyProperty **) myalloc(sizeof(PlyProperty *)); - else - elem->props = (PlyProperty **) realloc(elem->props, - sizeof(PlyProperty *) * (elem->nprops + 1)); - - elem->props[elem->nprops] = prop; - elem->nprops++; -} - - -/****************************************************************************** - Add a comment to a PLY file descriptor. - - Entry: - plyfile - PLY file descriptor - line - line containing comment -******************************************************************************/ - -void add_comment(PlyFile *plyfile, char *line) -{ - int i; - - /* skip over "comment" and leading spaces and tabs */ - i = 7; - while (line[i] == ' ' || line[i] == '\t') - i++; - - ply_put_comment(plyfile, &line[i]); -} - - -/****************************************************************************** - Add a some object information to a PLY file descriptor. - - Entry: - plyfile - PLY file descriptor - line - line containing text info -******************************************************************************/ - -void add_obj_info(PlyFile *plyfile, char *line) -{ - int i; - - /* skip over "obj_info" and leading spaces and tabs */ - i = 8; - while (line[i] == ' ' || line[i] == '\t') - i++; - - ply_put_obj_info(plyfile, &line[i]); -} - - -/****************************************************************************** - Copy a property. -******************************************************************************/ - -void copy_property(PlyProperty *dest, PlyProperty *src) -{ - dest->name = strdup(src->name); - dest->external_type = src->external_type; - dest->internal_type = src->internal_type; - dest->offset = src->offset; - - dest->is_list = src->is_list; - dest->count_external = src->count_external; - dest->count_internal = src->count_internal; - dest->count_offset = src->count_offset; -} - - -/****************************************************************************** - Allocate some memory. - - Entry: - size - amount of memory requested (in bytes) - lnum - line number from which memory was requested - fname - file name from which memory was requested -******************************************************************************/ - -static char *my_alloc(int size, int lnum, char *fname) -{ - char *ptr; - - ptr = (char *) malloc(size); - - if (ptr == 0) { - fprintf(stderr, "Memory allocation bombed on line %d in %s\n", lnum, fname); - } - - return (ptr); -} - diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index a928bd9a6ea..242f7c8ecef 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -306,6 +306,7 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, int motion) for(b_sce.objects.begin(b_ob); b_ob != b_sce.objects.end(); ++b_ob) { bool hide = (render_layer.use_viewport_visibility)? b_ob->hide(): b_ob->hide_render(); uint ob_layer = get_layer(b_ob->layers(), b_ob->layers_local_view(), object_is_light(*b_ob)); + CYCLES_LOCAL_LAYER_HACK(render_layer.use_localview, ob_layer); hide = hide || !(ob_layer & scene_layer); if(!hide) { diff --git a/intern/cycles/blender/blender_particles.cpp b/intern/cycles/blender/blender_particles.cpp index f591aaa6d83..d669aa34a68 100644 --- a/intern/cycles/blender/blender_particles.cpp +++ b/intern/cycles/blender/blender_particles.cpp @@ -144,16 +144,20 @@ void BlenderSync::sync_particles(Object *ob, BL::Object b_ob) BL::Object::particle_systems_iterator b_psys; for(b_ob.particle_systems.begin(b_psys); b_psys != b_ob.particle_systems.end(); ++b_psys) { if (use_particle_system(*b_psys)) { + int pa_index = 0; BL::ParticleSystem::particles_iterator b_pa; for(b_psys->particles.begin(b_pa), index = 0; b_pa != b_psys->particles.end(); ++b_pa, ++index) { if(use_particle(*b_pa)) { Particle pa; + pa.index = pa_index; pa.age = b_scene.frame_current() - b_pa->birth_time(); pa.lifetime = b_pa->lifetime(); ob->particles.push_back(pa); } + + ++pa_index; } } } diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp index c9d2d68da0a..ae28453a696 100644 --- a/intern/cycles/blender/blender_sync.cpp +++ b/intern/cycles/blender/blender_sync.cpp @@ -219,7 +219,9 @@ void BlenderSync::sync_render_layers(BL::SpaceView3D b_v3d, const char *layer) layer = layername.c_str(); } else { + render_layer.use_localview = (b_v3d.local_view() ? true : false); render_layer.scene_layer = get_layer(b_v3d.layers(), b_v3d.layers_local_view()); + CYCLES_LOCAL_LAYER_HACK(render_layer.use_localview, render_layer.scene_layer); render_layer.layer = render_layer.scene_layer; render_layer.holdout_layer = 0; render_layer.material_override = PointerRNA_NULL; @@ -245,6 +247,7 @@ void BlenderSync::sync_render_layers(BL::SpaceView3D b_v3d, const char *layer) render_layer.material_override = b_rlay->material_override(); render_layer.use_background = b_rlay->use_sky(); render_layer.use_viewport_visibility = false; + render_layer.use_localview = false; render_layer.samples = b_rlay->samples(); } diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h index 8c31c4b86ba..1a6c04db10c 100644 --- a/intern/cycles/blender/blender_sync.h +++ b/intern/cycles/blender/blender_sync.h @@ -127,10 +127,25 @@ private: BL::Material material_override; bool use_background; bool use_viewport_visibility; + bool use_localview; int samples; } render_layer; }; +/* we don't have spare bits for localview (normally 20-28) + * because PATH_RAY_LAYER_SHIFT uses 20-32. + * So - check if we have localview and if so, shift local + * view bits down to 1-8, since this is done for the view + * port only - it should be OK and not conflict with + * render layers. - Campbell. + * + * ... as an alternative we could use uint64_t + */ +#define CYCLES_LOCAL_LAYER_HACK(use_localview, layer) \ + if (use_localview) { \ + layer >>= 20; \ + } (void)0 + CCL_NAMESPACE_END #endif /* __BLENDER_SYNC_H__ */ diff --git a/intern/cycles/bvh/bvh.cpp b/intern/cycles/bvh/bvh.cpp index bdcd3b6ba19..4d3588452eb 100644 --- a/intern/cycles/bvh/bvh.cpp +++ b/intern/cycles/bvh/bvh.cpp @@ -378,19 +378,10 @@ void BVH::pack_instances(size_t nodes_size) int mesh_tri_offset = mesh->tri_offset; /* fill in node indexes for instances */ - if( - /* XXX, brecht. check this is needed!. it could be a bug elsewhere - * /mango/pro/scenes/04_2e/04_2e.blend r2158. on Ian's system 192.168.3.27 - campbell */ - (bvh->pack.is_leaf.size() != 0) && - - /* previously only checked this */ - bvh->pack.is_leaf[0]) - { + if((bvh->pack.is_leaf.size() != 0) && bvh->pack.is_leaf[0]) pack.object_node[object_offset++] = -noffset-1; - } - else { + else pack.object_node[object_offset++] = noffset; - } mesh_map[mesh] = pack.object_node[object_offset-1]; diff --git a/intern/cycles/device/device_opencl.cpp b/intern/cycles/device/device_opencl.cpp index 13ebeff70d2..c9ec7c75063 100644 --- a/intern/cycles/device/device_opencl.cpp +++ b/intern/cycles/device/device_opencl.cpp @@ -298,15 +298,12 @@ public: { string build_options = " -cl-fast-relaxed-math "; - /* Multi Closure for nVidia cards */ if(platform_name == "NVIDIA CUDA") build_options += "-D__KERNEL_SHADING__ -D__KERNEL_OPENCL_NVIDIA__ -cl-nv-maxrregcount=24 -cl-nv-verbose "; - - /* No Float3 for Apple */ + else if(platform_name == "Apple") build_options += "-D__CL_NO_FLOAT3__ -D__KERNEL_OPENCL_APPLE__ "; - - /* Basic shading for AMD cards (non Apple) */ + else if(platform_name == "AMD Accelerated Parallel Processing") build_options += "-D__CL_NO_FLOAT3__ -D__KERNEL_OPENCL_AMD__ "; diff --git a/intern/cycles/kernel/kernel_montecarlo.h b/intern/cycles/kernel/kernel_montecarlo.h index 939f3915b6c..afc53b1117a 100644 --- a/intern/cycles/kernel/kernel_montecarlo.h +++ b/intern/cycles/kernel/kernel_montecarlo.h @@ -87,8 +87,8 @@ __device_inline void sample_cos_hemisphere(const float3 N, } __device_inline void sample_uniform_hemisphere(const float3 N, - float randu, float randv, - float3 *omega_in, float *pdf) + float randu, float randv, + float3 *omega_in, float *pdf) { float z = randu; float r = sqrtf(max(0.0f, 1.0f - z*z)); diff --git a/intern/cycles/kernel/kernel_object.h b/intern/cycles/kernel/kernel_object.h index 18e0b1e8a87..4ff315ca265 100644 --- a/intern/cycles/kernel/kernel_object.h +++ b/intern/cycles/kernel/kernel_object.h @@ -169,20 +169,27 @@ __device int shader_pass_id(KernelGlobals *kg, ShaderData *sd) return kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2 + 1); } -__device float particle_age(KernelGlobals *kg, int particle) +__device_inline float particle_index(KernelGlobals *kg, int particle) { int offset = particle*PARTICLE_SIZE; float4 f = kernel_tex_fetch(__particles, offset); return f.x; } -__device float particle_lifetime(KernelGlobals *kg, int particle) +__device float particle_age(KernelGlobals *kg, int particle) { int offset = particle*PARTICLE_SIZE; float4 f = kernel_tex_fetch(__particles, offset); return f.y; } +__device float particle_lifetime(KernelGlobals *kg, int particle) +{ + int offset = particle*PARTICLE_SIZE; + float4 f = kernel_tex_fetch(__particles, offset); + return f.z; +} + CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h index 98ab9169c21..f5188345948 100644 --- a/intern/cycles/kernel/kernel_path.h +++ b/intern/cycles/kernel/kernel_path.h @@ -288,7 +288,7 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample, if(sd.flag & SD_HOLDOUT_MASK) holdout_weight = make_float3(1.0f, 1.0f, 1.0f); else - shader_holdout_eval(kg, &sd); + holdout_weight = shader_holdout_eval(kg, &sd); /* any throughput is ok, should all be identical here */ L_transparent += average(holdout_weight*throughput); @@ -655,7 +655,7 @@ __device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sam if(sd.flag & SD_HOLDOUT_MASK) holdout_weight = make_float3(1.0f, 1.0f, 1.0f); else - shader_holdout_eval(kg, &sd); + holdout_weight = shader_holdout_eval(kg, &sd); /* any throughput is ok, should all be identical here */ L_transparent += average(holdout_weight*throughput); diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index d204b114b8e..30d45ad1118 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -172,6 +172,8 @@ enum PathRayFlag { PATH_RAY_ALL = (1|2|4|8|16|32|64|128|256|512), + /* this gives collisions with localview bits + * see: CYCLES_LOCAL_LAYER_HACK(), grr - Campbell */ PATH_RAY_LAYER_SHIFT = (32-20) }; diff --git a/intern/cycles/kernel/svm/svm_geometry.h b/intern/cycles/kernel/svm/svm_geometry.h index 88127b56474..3cfce1d087a 100644 --- a/intern/cycles/kernel/svm/svm_geometry.h +++ b/intern/cycles/kernel/svm/svm_geometry.h @@ -101,6 +101,12 @@ __device void svm_node_particle_info(KernelGlobals *kg, ShaderData *sd, float *s float data; switch(type) { + case NODE_INFO_PAR_INDEX: { + uint particle_id = object_particle_id(kg, sd->object); + data = particle_index(kg, particle_id); + stack_store_float(stack, out_offset, data); + break; + } case NODE_INFO_PAR_AGE: { uint particle_id = object_particle_id(kg, sd->object); data = particle_age(kg, particle_id); diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h index 3a04da450ba..5be50a2a6cc 100644 --- a/intern/cycles/kernel/svm/svm_types.h +++ b/intern/cycles/kernel/svm/svm_types.h @@ -114,6 +114,7 @@ typedef enum NodeObjectInfo { } NodeObjectInfo; typedef enum NodeParticleInfo { + NODE_INFO_PAR_INDEX, NODE_INFO_PAR_AGE, NODE_INFO_PAR_LIFETIME } NodeParticleInfo; diff --git a/intern/cycles/render/light.cpp b/intern/cycles/render/light.cpp index 6c03d0859a7..d00b242d153 100644 --- a/intern/cycles/render/light.cpp +++ b/intern/cycles/render/light.cpp @@ -194,10 +194,11 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen /* sum area */ if(have_emission) { + bool transform_applied = mesh->transform_applied; Transform tfm = object->tfm; int object_id = j; - if(mesh->transform_applied) + if(transform_applied) object_id = ~object_id; for(size_t i = 0; i < mesh->triangles.size(); i++) { @@ -211,9 +212,15 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen offset++; Mesh::Triangle t = mesh->triangles[i]; - float3 p1 = transform_point(&tfm, mesh->verts[t.v[0]]); - float3 p2 = transform_point(&tfm, mesh->verts[t.v[1]]); - float3 p3 = transform_point(&tfm, mesh->verts[t.v[2]]); + float3 p1 = mesh->verts[t.v[0]]; + float3 p2 = mesh->verts[t.v[1]]; + float3 p3 = mesh->verts[t.v[2]]; + + if(!transform_applied) { + p1 = transform_point(&tfm, p1); + p2 = transform_point(&tfm, p2); + p3 = transform_point(&tfm, p3); + } totarea += triangle_area(p1, p2, p3); } diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index 842eb3e580c..71b4fcbfbf0 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -1817,12 +1817,15 @@ void ObjectInfoNode::compile(OSLCompiler& compiler) ParticleInfoNode::ParticleInfoNode() : ShaderNode("particle_info") { + add_output("Index", SHADER_SOCKET_FLOAT); add_output("Age", SHADER_SOCKET_FLOAT); add_output("Lifetime", SHADER_SOCKET_FLOAT); } void ParticleInfoNode::attributes(AttributeRequestSet *attributes) { + if(!output("Index")->links.empty()) + attributes->add(ATTR_STD_PARTICLE); if(!output("Age")->links.empty()) attributes->add(ATTR_STD_PARTICLE); if(!output("Lifetime")->links.empty()) @@ -1835,6 +1838,12 @@ void ParticleInfoNode::compile(SVMCompiler& compiler) { ShaderOutput *out; + out = output("Index"); + if(!out->links.empty()) { + compiler.stack_assign(out); + compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_INDEX, out->stack_offset); + } + out = output("Age"); if(!out->links.empty()) { compiler.stack_assign(out); diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp index 6de7eaea343..0fe227fd171 100644 --- a/intern/cycles/render/object.cpp +++ b/intern/cycles/render/object.cpp @@ -111,8 +111,9 @@ void Object::apply_transform() mesh->compute_bounds(); compute_bounds(false); } - - tfm = transform_identity(); + + /* tfm is not reset to identity, all code that uses it needs to check the + transform_applied boolean */ } void Object::tag_update(Scene *scene) @@ -269,7 +270,7 @@ void ObjectManager::device_update_particles(Device *device, DeviceScene *dscene, /* pack in texture */ int offset = i*PARTICLE_SIZE; - particles[offset] = make_float4(pa.age, pa.lifetime, 0.0f, 0.0f); + particles[offset] = make_float4(pa.index, pa.age, pa.lifetime, 0.0f); i++; diff --git a/intern/cycles/render/object.h b/intern/cycles/render/object.h index 6d674731b07..9b2f5bc8768 100644 --- a/intern/cycles/render/object.h +++ b/intern/cycles/render/object.h @@ -36,6 +36,7 @@ struct Transform; /* Object */ struct Particle { + int index; float age; float lifetime; }; diff --git a/intern/cycles/subd/subd_build.cpp b/intern/cycles/subd/subd_build.cpp index c8181838ec3..312980f1fa2 100644 --- a/intern/cycles/subd/subd_build.cpp +++ b/intern/cycles/subd/subd_build.cpp @@ -117,7 +117,7 @@ Patch *SubdAccBuilder::run(SubdFace *face) memcpy(patch->hull, position, sizeof(float3)*20); return patch; } - else if(face->num_edges() == 4) { + else if(face->num_edges() == 4) { GregoryQuadPatch *patch = new GregoryQuadPatch(); memcpy(patch->hull, position, sizeof(float3)*20); return patch; @@ -644,7 +644,7 @@ Patch *SubdLinearBuilder::run(SubdFace *face) hull = lpatch->hull; patch = lpatch; } - else if(face->num_edges() == 4) { + else if(face->num_edges() == 4) { LinearQuadPatch *lpatch = new LinearQuadPatch(); hull = lpatch->hull; patch = lpatch; diff --git a/intern/cycles/util/util_cache.cpp b/intern/cycles/util/util_cache.cpp index 2924ed30b88..55ed50b2ca6 100644 --- a/intern/cycles/util/util_cache.cpp +++ b/intern/cycles/util/util_cache.cpp @@ -26,6 +26,12 @@ #include "util_path.h" #include "util_types.h" +#include <boost/version.hpp> + +#if (BOOST_VERSION < 104400) +# define BOOST_FILESYSTEM_VERSION 2 +#endif + #include <boost/filesystem.hpp> #include <boost/algorithm/string.hpp> @@ -115,7 +121,11 @@ void Cache::clear_except(const string& name, const set<string>& except) boost::filesystem::directory_iterator it(dir), it_end; for(; it != it_end; it++) { +#if (BOOST_FILESYSTEM_VERSION == 2) + string filename = it->path().filename(); +#else string filename = it->path().filename().string(); +#endif if(boost::starts_with(filename, name)) if(except.find(filename) == except.end()) diff --git a/intern/cycles/util/util_path.cpp b/intern/cycles/util/util_path.cpp index 53dbfe9a42c..a571fe81118 100644 --- a/intern/cycles/util/util_path.cpp +++ b/intern/cycles/util/util_path.cpp @@ -26,6 +26,12 @@ OIIO_NAMESPACE_USING #include <stdio.h> +#include <boost/version.hpp> + +#if (BOOST_VERSION < 104400) +# define BOOST_FILESYSTEM_VERSION 2 +#endif + #include <boost/filesystem.hpp> #include <boost/algorithm/string.hpp> @@ -58,7 +64,11 @@ string path_user_get(const string& sub) string path_filename(const string& path) { +#if (BOOST_FILESYSTEM_VERSION == 2) + return boost::filesystem::path(path).filename(); +#else return boost::filesystem::path(path).filename().string(); +#endif } string path_dirname(const string& path) diff --git a/intern/decimation/intern/LOD_QuadricEditor.cpp b/intern/decimation/intern/LOD_QuadricEditor.cpp index b56f6a5b520..fbaf0c1180f 100644 --- a/intern/decimation/intern/LOD_QuadricEditor.cpp +++ b/intern/decimation/intern/LOD_QuadricEditor.cpp @@ -174,7 +174,7 @@ BuildQuadrics( vector<LOD_Edge>::iterator edge_it = edges.begin(); vector<LOD_Edge>::const_iterator edge_end = edges.end(); - for (; edge_it != edge_end; ++edge_it) { + for (; edge_it != edge_end; ++edge_it) { MT_Vector3 target = TargetVertex(*edge_it); @@ -235,7 +235,7 @@ ComputeEdgeCosts( vector<LOD_EdgeInd>::const_iterator edge_it = edges.begin(); vector<LOD_EdgeInd>::const_iterator edge_end = edges.end(); - for (; edge_it != edge_end; ++edge_it) { + for (; edge_it != edge_end; ++edge_it) { MT_Vector3 target = TargetVertex(edge_set[*edge_it]); diff --git a/intern/elbeem/intern/mvmcoords.cpp b/intern/elbeem/intern/mvmcoords.cpp index 426b8c6606d..281a9656fcf 100644 --- a/intern/elbeem/intern/mvmcoords.cpp +++ b/intern/elbeem/intern/mvmcoords.cpp @@ -16,6 +16,13 @@ #include "mvmcoords.h" #include <algorithm> + +#if defined(_MSC_VER) && _MSC_VER > 1600 +// sdt::greater +#include <functional> +#endif + + using std::vector; void MeanValueMeshCoords::clear() diff --git a/intern/ghost/GHOST_IWindow.h b/intern/ghost/GHOST_IWindow.h index 5005718e4a5..b606294e97d 100644 --- a/intern/ghost/GHOST_IWindow.h +++ b/intern/ghost/GHOST_IWindow.h @@ -278,7 +278,7 @@ public: GHOST_TUns8 mask[16][2], int hotX, int hotY) = 0; - + virtual GHOST_TSuccess setCustomCursorShape(GHOST_TUns8 *bitmap, GHOST_TUns8 *mask, int sizex, int sizey, diff --git a/intern/ghost/intern/GHOST_DisplayManagerX11.cpp b/intern/ghost/intern/GHOST_DisplayManagerX11.cpp index d719a4caa55..0bd90854a31 100644 --- a/intern/ghost/intern/GHOST_DisplayManagerX11.cpp +++ b/intern/ghost/intern/GHOST_DisplayManagerX11.cpp @@ -48,7 +48,7 @@ GHOST_DisplayManagerX11( GHOST_DisplayManager(), m_system(system) { - //nothing to do. + /* nothing to do. */ } GHOST_TSuccess @@ -87,7 +87,7 @@ getNumDisplaySettings( XF86VidModeGetAllModeLines(dpy, DefaultScreen(dpy), &numSettings, &vidmodes); #else - // We only have one X11 setting at the moment. + /* We only have one X11 setting at the moment. */ GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n"); numSettings = GHOST_TInt32(1); #endif @@ -144,8 +144,8 @@ getDisplaySetting( setting.bpp = DefaultDepth(x_display, DefaultScreen(x_display)); #endif - // Don't think it's possible to get this value from X! - // So let's guess!! + /* Don't think it's possible to get this value from X! + * So let's guess!! */ setting.frequency = 60; return GHOST_kSuccess; @@ -171,11 +171,10 @@ setCurrentDisplaySetting( const GHOST_DisplaySetting& setting) { #ifdef WITH_X11_XF86VMODE - // - // Mode switching code ported from Quake 2: - // ftp://ftp.idsoftware.com/idstuff/source/q2source-3.21.zip - // See linux/gl_glx.c:GLimp_SetMode - // + /* Mode switching code ported from Quake 2: + * ftp: ftp.idsoftware.com/idstuff/source/q2source-3.21.zip + * See linux/gl_glx.c:GLimp_SetMode + */ int majorVersion, minorVersion; XF86VidModeModeInfo **vidmodes; Display *dpy = m_system->getXDisplay(); @@ -187,7 +186,7 @@ setCurrentDisplaySetting( scrnum = DefaultScreen(dpy); - // Get video mode list + /* Get video mode list */ majorVersion = minorVersion = 0; if (!XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion)) { fprintf(stderr, "Error: XF86VidMode extension missing!\n"); @@ -228,20 +227,21 @@ setCurrentDisplaySetting( actualWidth, actualHeight); # endif - // change to the mode + /* change to the mode */ XF86VidModeSwitchToMode(dpy, scrnum, vidmodes[best_fit]); - // Move the viewport to top left + /* Move the viewport to top left */ XF86VidModeSetViewPort(dpy, scrnum, 0, 0); } - else + else { return GHOST_kFailure; + } XFlush(dpy); return GHOST_kSuccess; #else - // Just pretend the request was successful. + /* Just pretend the request was successful. */ return GHOST_kSuccess; #endif } diff --git a/intern/ghost/intern/GHOST_DropTargetX11.cpp b/intern/ghost/intern/GHOST_DropTargetX11.cpp index c1cc55b332a..e2e15277a99 100644 --- a/intern/ghost/intern/GHOST_DropTargetX11.cpp +++ b/intern/ghost/intern/GHOST_DropTargetX11.cpp @@ -144,23 +144,23 @@ void GHOST_DropTargetX11::UrlDecode(char *decodedOut, int bufferSize, const char break; } - // We are now converting + /* We are now converting */ state = STATE_CONVERTING; break; case STATE_CONVERTING: bothDigits = true; - // Create a buffer to hold the hex. For example, if %20, this - // buffer would hold 20 (in ASCII) + /* Create a buffer to hold the hex. For example, if %20, this + * buffer would hold 20 (in ASCII) */ memset(tempNumBuf, 0, sizeof(tempNumBuf)); - // Conversion complete (i.e. don't convert again next iter) + /* Conversion complete (i.e. don't convert again next iter) */ state = STATE_SEARCH; strncpy(tempNumBuf, &encodedIn[i], 2); - // Ensure both characters are hexadecimal + /* Ensure both characters are hexadecimal */ for (j = 0; j < 2; ++j) { if (!isxdigit(tempNumBuf[j])) @@ -170,16 +170,16 @@ void GHOST_DropTargetX11::UrlDecode(char *decodedOut, int bufferSize, const char if (!bothDigits) break; - // Convert two hexadecimal characters into one character + /* Convert two hexadecimal characters into one character */ sscanf(tempNumBuf, "%x", &asciiCharacter); - // Ensure we aren't going to overflow + /* Ensure we aren't going to overflow */ assert(strlen(decodedOut) < bufferSize); - // Concatenate this character onto the output + /* Concatenate this character onto the output */ strncat(decodedOut, (char *)&asciiCharacter, 1); - // Skip the next character + /* Skip the next character */ i++; break; } diff --git a/intern/ghost/intern/GHOST_NDOFManagerX11.cpp b/intern/ghost/intern/GHOST_NDOFManagerX11.cpp index bd285bc7a27..49e7def8730 100644 --- a/intern/ghost/intern/GHOST_NDOFManagerX11.cpp +++ b/intern/ghost/intern/GHOST_NDOFManagerX11.cpp @@ -58,8 +58,11 @@ GHOST_NDOFManagerX11::GHOST_NDOFManagerX11(GHOST_System& sys) } } else { +#ifdef DEBUG + /* annoying for official builds, just adds noise and most prople don't own these */ puts("ndof: spacenavd not found"); /* This isn't a hard error, just means the user doesn't have a 3D mouse. */ +#endif } } diff --git a/intern/ghost/intern/GHOST_SystemPathsX11.cpp b/intern/ghost/intern/GHOST_SystemPathsX11.cpp index 83f7e87977c..35bebd588c3 100644 --- a/intern/ghost/intern/GHOST_SystemPathsX11.cpp +++ b/intern/ghost/intern/GHOST_SystemPathsX11.cpp @@ -38,11 +38,11 @@ #include <sys/time.h> #include <unistd.h> -#include <stdio.h> // for fprintf only -#include <cstdlib> // for exit +#include <stdio.h> /* for fprintf only */ +#include <cstdlib> /* for exit */ -#include <pwd.h> // for get home without use getenv() -#include <limits.h> // for PATH_MAX +#include <pwd.h> /* for get home without use getenv() */ +#include <limits.h> /* for PATH_MAX */ #ifdef PREFIX static const char *static_path = PREFIX "/share"; diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp index 03a952fafb3..e8f172f8b1c 100644 --- a/intern/ghost/intern/GHOST_SystemX11.cpp +++ b/intern/ghost/intern/GHOST_SystemX11.cpp @@ -32,7 +32,6 @@ * \ingroup GHOST */ - #include "GHOST_SystemX11.h" #include "GHOST_WindowX11.h" #include "GHOST_WindowManager.h" @@ -44,11 +43,11 @@ #include "GHOST_DisplayManagerX11.h" #include "GHOST_EventDragnDrop.h" #ifdef WITH_INPUT_NDOF -#include "GHOST_NDOFManagerX11.h" +# include "GHOST_NDOFManagerX11.h" #endif #ifdef WITH_XDND -#include "GHOST_DropTargetX11.h" +# include "GHOST_DropTargetX11.h" #endif #include "GHOST_Debug.h" @@ -61,20 +60,19 @@ #include <X11/XF86keysym.h> #endif -// For timing - +/* For timing */ #include <sys/time.h> #include <unistd.h> #include <iostream> #include <vector> -#include <stdio.h> // for fprintf only -#include <cstdlib> // for exit +#include <stdio.h> /* for fprintf only */ +#include <cstdlib> /* for exit */ static GHOST_TKey convertXKey(KeySym key); -//these are for copy and select copy +/* these are for copy and select copy */ static char *txt_cut_buffer = NULL; static char *txt_select_buffer = NULL; @@ -90,7 +88,7 @@ GHOST_SystemX11( if (!m_display) { std::cerr << "Unable to open a display" << std::endl; - abort(); //was return before, but this would just mean it will crash later + abort(); /* was return before, but this would just mean it will crash later */ } #if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING) @@ -128,13 +126,13 @@ GHOST_SystemX11( m_last_warp = 0; - // compute the initial time + /* compute the initial time */ timeval tv; if (gettimeofday(&tv, NULL) == -1) { GHOST_ASSERT(false, "Could not instantiate timer!"); } - // Taking care not to overflow the tv.tv_sec*1000 + /* Taking care not to overflow the tv.tv_sec*1000 */ m_start_time = GHOST_TUns64(tv.tv_sec) * 1000 + tv.tv_usec / 1000; @@ -190,7 +188,7 @@ getMilliSeconds() const GHOST_ASSERT(false, "Could not compute time!"); } - // Taking care not to overflow the tv.tv_sec*1000 + /* Taking care not to overflow the tv.tv_sec*1000 */ return GHOST_TUns64(tv.tv_sec) * 1000 + tv.tv_usec / 1000 - m_start_time; } @@ -254,16 +252,16 @@ createWindow( - window = new GHOST_WindowX11( - this, m_display, title, left, top, width, height, state, parentWindow, type, stereoVisual - ); + window = new GHOST_WindowX11(this, m_display, title, + left, top, width, height, + state, parentWindow, type, stereoVisual); if (window) { - // Both are now handle in GHOST_WindowX11.cpp - // Focus and Delete atoms. + /* Both are now handle in GHOST_WindowX11.cpp + * Focus and Delete atoms. */ if (window->getValid()) { - // Store the pointer to the window + /* Store the pointer to the window */ m_windowManager->addWindow(window); m_windowManager->setActiveWindow(window); pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window) ); @@ -313,10 +311,10 @@ findGhostWindow( if (xwind == 0) return NULL; - // It is not entirely safe to do this as the backptr may point - // to a window that has recently been removed. - // We should always check the window manager's list of windows - // and only process events on these windows. + /* It is not entirely safe to do this as the backptr may point + * to a window that has recently been removed. + * We should always check the window manager's list of windows + * and only process events on these windows. */ vector<GHOST_IWindow *> & win_vec = m_windowManager->getWindows(); @@ -411,8 +409,8 @@ GHOST_SystemX11:: processEvents( bool waitForEvent) { - // Get all the current events -- translate them into - // ghost events and call base class pushEvent() method. + /* Get all the current events -- translate them into + * ghost events and call base class pushEvent() method. */ bool anyProcessed = false; @@ -519,8 +517,8 @@ GHOST_SystemX11::processEvent(XEvent *xe) XExposeEvent & xee = xe->xexpose; if (xee.count == 0) { - // Only generate a single expose event - // per read of the event queue. + /* Only generate a single expose event + * per read of the event queue. */ g_event = new GHOST_Event( @@ -761,7 +759,7 @@ GHOST_SystemX11::processEvent(XEvent *xe) break; } - // change of size, border, layer etc. + /* change of size, border, layer etc. */ case ConfigureNotify: { /* XConfigureEvent & xce = xe->xconfigure; */ @@ -780,12 +778,11 @@ GHOST_SystemX11::processEvent(XEvent *xe) { XFocusChangeEvent &xfe = xe->xfocus; - // TODO: make sure this is the correct place for activate/deactivate + /* TODO: make sure this is the correct place for activate/deactivate */ // printf("X: focus %s for window %d\n", xfe.type == FocusIn ? "in" : "out", (int) xfe.window); - // May have to look at the type of event and filter some - // out. - + /* May have to look at the type of event and filter some out. */ + GHOST_TEventType gtype = (xfe.type == FocusIn) ? GHOST_kEventWindowActivate : GHOST_kEventWindowDeactivate; @@ -860,7 +857,7 @@ GHOST_SystemX11::processEvent(XEvent *xe) case DestroyNotify: ::exit(-1); - // We're not interested in the following things.(yet...) + /* We're not interested in the following things.(yet...) */ case NoExpose: case GraphicsExpose: break; @@ -945,8 +942,12 @@ GHOST_SystemX11::processEvent(XEvent *xe) nxe.xselection.target = xse->target; nxe.xselection.time = xse->time; - /*Check to see if the requestor is asking for String*/ - if (xse->target == utf8_string || xse->target == string || xse->target == compound_text || xse->target == c_string) { + /* Check to see if the requestor is asking for String */ + if (xse->target == utf8_string || + xse->target == string || + xse->target == compound_text || + xse->target == c_string) + { if (xse->selection == XInternAtom(m_display, "PRIMARY", False)) { XChangeProperty(m_display, xse->requestor, xse->property, xse->target, 8, PropModeReplace, (unsigned char *)txt_select_buffer, strlen(txt_select_buffer)); @@ -968,11 +969,11 @@ GHOST_SystemX11::processEvent(XEvent *xe) XFlush(m_display); } else { - //Change property to None because we do not support anything but STRING + /* Change property to None because we do not support anything but STRING */ nxe.xselection.property = None; } - //Send the event to the client 0 0 == False, SelectionNotify + /* Send the event to the client 0 0 == False, SelectionNotify */ XSendEvent(m_display, xse->requestor, 0, 0, &nxe); XFlush(m_display); break; @@ -1023,14 +1024,14 @@ getModifierKeys( GHOST_ModifierKeys& keys) const { - // analyse the masks retuned from XQueryPointer. + /* analyse the masks retuned from XQueryPointer. */ memset((void *)m_keyboard_vector, 0, sizeof(m_keyboard_vector)); XQueryKeymap(m_display, (char *)m_keyboard_vector); - // now translate key symobols into keycodes and - // test with vector. + /* now translate key symobols into keycodes and + * test with vector. */ const static KeyCode shift_l = XKeysymToKeycode(m_display, XK_Shift_L); const static KeyCode shift_r = XKeysymToKeycode(m_display, XK_Shift_R); @@ -1041,16 +1042,16 @@ getModifierKeys( const static KeyCode super_l = XKeysymToKeycode(m_display, XK_Super_L); const static KeyCode super_r = XKeysymToKeycode(m_display, XK_Super_R); - // shift + /* shift */ keys.set(GHOST_kModifierKeyLeftShift, ((m_keyboard_vector[shift_l >> 3] >> (shift_l & 7)) & 1) != 0); keys.set(GHOST_kModifierKeyRightShift, ((m_keyboard_vector[shift_r >> 3] >> (shift_r & 7)) & 1) != 0); - // control + /* control */ keys.set(GHOST_kModifierKeyLeftControl, ((m_keyboard_vector[control_l >> 3] >> (control_l & 7)) & 1) != 0); keys.set(GHOST_kModifierKeyRightControl, ((m_keyboard_vector[control_r >> 3] >> (control_r & 7)) & 1) != 0); - // alt + /* alt */ keys.set(GHOST_kModifierKeyLeftAlt, ((m_keyboard_vector[alt_l >> 3] >> (alt_l & 7)) & 1) != 0); keys.set(GHOST_kModifierKeyRightAlt, ((m_keyboard_vector[alt_r >> 3] >> (alt_r & 7)) & 1) != 0); - // super (windows) - only one GHOST-kModifierKeyOS, so mapping to either + /* super (windows) - only one GHOST-kModifierKeyOS, so mapping to either */ keys.set(GHOST_kModifierKeyOS, ( ((m_keyboard_vector[super_l >> 3] >> (super_l & 7)) & 1) || ((m_keyboard_vector[super_r >> 3] >> (super_r & 7)) & 1) ) != 0); @@ -1123,9 +1124,9 @@ setCursorPosition( GHOST_TInt32 y ) { - // This is a brute force move in screen coordinates - // XWarpPointer does relative moves so first determine the - // current pointer position. + /* This is a brute force move in screen coordinates + * XWarpPointer does relative moves so first determine the + * current pointer position. */ int cx, cy; if (getCursorPosition(cx, cy) == GHOST_kFailure) { @@ -1336,15 +1337,15 @@ convertXKey(KeySym key) /* from xclip.c xcout() v0.11 */ -#define XCLIB_XCOUT_NONE 0 /* no context */ +#define XCLIB_XCOUT_NONE 0 /* no context */ #define XCLIB_XCOUT_SENTCONVSEL 1 /* sent a request */ -#define XCLIB_XCOUT_INCR 2 /* in an incr loop */ +#define XCLIB_XCOUT_INCR 2 /* in an incr loop */ #define XCLIB_XCOUT_FALLBACK 3 /* STRING failed, need fallback to UTF8 */ #define XCLIB_XCOUT_FALLBACK_UTF8 4 /* UTF8 failed, move to compouned */ #define XCLIB_XCOUT_FALLBACK_COMP 5 /* compouned failed, move to text. */ #define XCLIB_XCOUT_FALLBACK_TEXT 6 -// Retrieves the contents of a selections. +/* Retrieves the contents of a selections. */ void GHOST_SystemX11::getClipboard_xcout(XEvent evt, Atom sel, Atom target, unsigned char **txt, unsigned long *len, unsigned int *context) const @@ -1361,15 +1362,15 @@ void GHOST_SystemX11::getClipboard_xcout(XEvent evt, Window win = window->getXWindow(); switch (*context) { - // There is no context, do an XConvertSelection() + /* There is no context, do an XConvertSelection() */ case XCLIB_XCOUT_NONE: - // Initialise return length to 0 + /* Initialise return length to 0 */ if (*len > 0) { free(*txt); *len = 0; } - // Send a selection request + /* Send a selection request */ XConvertSelection(m_display, sel, target, m_xclip_out, win, CurrentTime); *context = XCLIB_XCOUT_SENTCONVSEL; return; @@ -1391,22 +1392,22 @@ void GHOST_SystemX11::getClipboard_xcout(XEvent evt, return; } - // find the size and format of the data in property + /* find the size and format of the data in property */ XGetWindowProperty(m_display, win, m_xclip_out, 0, 0, False, AnyPropertyType, &pty_type, &pty_format, &pty_items, &pty_size, &buffer); XFree(buffer); if (pty_type == m_incr) { - // start INCR mechanism by deleting property + /* start INCR mechanism by deleting property */ XDeleteProperty(m_display, win, m_xclip_out); XFlush(m_display); *context = XCLIB_XCOUT_INCR; return; } - // if it's not incr, and not format == 8, then there's - // nothing in the selection (that xclip understands, anyway) + /* if it's not incr, and not format == 8, then there's + * nothing in the selection (that xclip understands, anyway) */ if (pty_format != 8) { *context = XCLIB_XCOUT_NONE; @@ -1418,73 +1419,73 @@ void GHOST_SystemX11::getClipboard_xcout(XEvent evt, False, AnyPropertyType, &pty_type, &pty_format, &pty_items, &pty_size, &buffer); - // finished with property, delete it + /* finished with property, delete it */ XDeleteProperty(m_display, win, m_xclip_out); - // copy the buffer to the pointer for returned data + /* copy the buffer to the pointer for returned data */ ltxt = (unsigned char *) malloc(pty_items); memcpy(ltxt, buffer, pty_items); - // set the length of the returned data + /* set the length of the returned data */ *len = pty_items; *txt = ltxt; - // free the buffer + /* free the buffer */ XFree(buffer); *context = XCLIB_XCOUT_NONE; - // complete contents of selection fetched, return 1 + /* complete contents of selection fetched, return 1 */ return; case XCLIB_XCOUT_INCR: - // To use the INCR method, we basically delete the - // property with the selection in it, wait for an - // event indicating that the property has been created, - // then read it, delete it, etc. + /* To use the INCR method, we basically delete the + * property with the selection in it, wait for an + * event indicating that the property has been created, + * then read it, delete it, etc. */ - // make sure that the event is relevant + /* make sure that the event is relevant */ if (evt.type != PropertyNotify) return; - // skip unless the property has a new value + /* skip unless the property has a new value */ if (evt.xproperty.state != PropertyNewValue) return; - // check size and format of the property + /* check size and format of the property */ XGetWindowProperty(m_display, win, m_xclip_out, 0, 0, False, AnyPropertyType, &pty_type, &pty_format, &pty_items, &pty_size, (unsigned char **) &buffer); if (pty_format != 8) { - // property does not contain text, delete it - // to tell the other X client that we have read - // it and to send the next property + /* property does not contain text, delete it + * to tell the other X client that we have read + * it and to send the next property */ XFree(buffer); XDeleteProperty(m_display, win, m_xclip_out); return; } if (pty_size == 0) { - // no more data, exit from loop + /* no more data, exit from loop */ XFree(buffer); XDeleteProperty(m_display, win, m_xclip_out); *context = XCLIB_XCOUT_NONE; - // this means that an INCR transfer is now - // complete, return 1 + /* this means that an INCR transfer is now + * complete, return 1 */ return; } XFree(buffer); - // if we have come this far, the propery contains - // text, we know the size. + /* if we have come this far, the property contains + * text, we know the size. */ XGetWindowProperty(m_display, win, m_xclip_out, 0, (long) pty_size, False, AnyPropertyType, &pty_type, &pty_format, &pty_items, &pty_size, (unsigned char **) &buffer); - // allocate memory to accommodate data in *txt + /* allocate memory to accommodate data in *txt */ if (*len == 0) { *len = pty_items; ltxt = (unsigned char *) malloc(*len); @@ -1494,13 +1495,13 @@ void GHOST_SystemX11::getClipboard_xcout(XEvent evt, ltxt = (unsigned char *) realloc(ltxt, *len); } - // add data to ltxt + /* add data to ltxt */ memcpy(<xt[*len - pty_items], buffer, pty_items); *txt = ltxt; XFree(buffer); - // delete property to get the next item + /* delete property to get the next item */ XDeleteProperty(m_display, win, m_xclip_out); XFlush(m_display); return; @@ -1514,7 +1515,7 @@ GHOST_TUns8 *GHOST_SystemX11::getClipboard(bool selection) const Atom target = m_utf8_string; Window owner; - // from xclip.c doOut() v0.11 + /* from xclip.c doOut() v0.11 */ unsigned char *sel_buf; unsigned long sel_len = 0; XEvent evt; diff --git a/intern/ghost/intern/GHOST_Window.h b/intern/ghost/intern/GHOST_Window.h index 91a974bde19..10a6a57b9fe 100644 --- a/intern/ghost/intern/GHOST_Window.h +++ b/intern/ghost/intern/GHOST_Window.h @@ -335,7 +335,7 @@ protected: /** Modified state : are there unsaved changes */ bool m_isUnsavedChanges; - /** Stores wether this is a full screen window. */ + /** Stores whether this is a full screen window. */ bool m_fullScreen; /** Stereo visual created. Only necessary for 'real' stereo support, diff --git a/intern/ghost/intern/GHOST_WindowNULL.h b/intern/ghost/intern/GHOST_WindowNULL.h index dcbb7d2b346..e3d092101b0 100644 --- a/intern/ghost/intern/GHOST_WindowNULL.h +++ b/intern/ghost/intern/GHOST_WindowNULL.h @@ -81,9 +81,9 @@ protected: GHOST_TSuccess activateDrawingContext( ) { return GHOST_kFailure; } ~GHOST_WindowNULL( ) { /* nothing */ } GHOST_TSuccess setWindowCursorVisibility( bool visible ) { return GHOST_kSuccess; } - GHOST_TSuccess setState(GHOST_TWindowState state) { return GHOST_kSuccess; } + GHOST_TSuccess setState(GHOST_TWindowState state) { return GHOST_kSuccess; } GHOST_TWindowState getState() const { return GHOST_kWindowStateNormal; } - GHOST_TSuccess invalidate() { return GHOST_kSuccess; } + GHOST_TSuccess invalidate() { return GHOST_kSuccess; } GHOST_TSuccess setOrder(GHOST_TWindowOrder order) { return GHOST_kSuccess; } diff --git a/intern/ghost/intern/GHOST_WindowWin32.cpp b/intern/ghost/intern/GHOST_WindowWin32.cpp index e3fe28e2e64..3a6e646de11 100644 --- a/intern/ghost/intern/GHOST_WindowWin32.cpp +++ b/intern/ghost/intern/GHOST_WindowWin32.cpp @@ -1343,7 +1343,7 @@ static int EnumPixelFormats(HDC hdc) ::DescribePixelFormat(hdc, i, sizeof(PIXELFORMATDESCRIPTOR), &pfd); w = WeightPixelFormat(pfd); // be strict on stereo - if (!((sPreferredFormat.dwFlags ^ pfd.dwFlags) & PFD_STEREO)) { + if (!((sPreferredFormat.dwFlags ^ pfd.dwFlags) & PFD_STEREO)) { if (w > weight) { weight = w; iPixelFormat = i; diff --git a/intern/ghost/intern/GHOST_WindowX11.cpp b/intern/ghost/intern/GHOST_WindowX11.cpp index 80d5b5a4652..3dc10d17169 100644 --- a/intern/ghost/intern/GHOST_WindowX11.cpp +++ b/intern/ghost/intern/GHOST_WindowX11.cpp @@ -39,7 +39,7 @@ #include "GHOST_DropTargetX11.h" #endif -// For standard X11 cursors +/* For standard X11 cursors */ #include <X11/cursorfont.h> #include <X11/Xatom.h> @@ -53,8 +53,8 @@ #include <algorithm> #include <string> -// For obscure full screen mode stuuf -// lifted verbatim from blut. +/* For obscure full screen mode stuuf + * lifted verbatim from blut. */ typedef struct { long flags; @@ -95,7 +95,7 @@ typedef struct { f.write('\n') */ -// See the python script above to regenerate the 48x48 icon within blender +/* See the python script above to regenerate the 48x48 icon within blender */ #define BLENDER_ICON_WIDTH 48 #define BLENDER_ICON_HEIGHT 48 static unsigned char BLENDER_ICON_48x48x24[] = { @@ -178,13 +178,13 @@ GHOST_WindowX11( m_custom_cursor(None) { - // Set up the minimum atrributes that we require and see if - // X can find us a visual matching those requirements. + /* Set up the minimum atrributes that we require and see if + * X can find us a visual matching those requirements. */ int attributes[40], i, samples; Atom atoms[2]; int natom; - int glxVersionMajor, glxVersionMinor; // As in GLX major.minor + int glxVersionMajor, glxVersionMinor; /* As in GLX major.minor */ #ifdef WITH_X11_XINPUT /* initialize incase X11 fails to load */ @@ -251,11 +251,11 @@ GHOST_WindowX11( } } - // Create a bunch of attributes needed to create an X window. + /* Create a bunch of attributes needed to create an X window. */ - // First create a colormap for the window and visual. - // This seems pretty much a legacy feature as we are in rgba mode anyway. + /* First create a colormap for the window and visual. + * This seems pretty much a legacy feature as we are in rgba mode anyway. */ XSetWindowAttributes xattributes; memset(&xattributes, 0, sizeof(xattributes)); @@ -268,7 +268,7 @@ GHOST_WindowX11( xattributes.border_pixel = 0; - // Specify which events we are interested in hearing. + /* Specify which events we are interested in hearing. */ xattributes.event_mask = ExposureMask | StructureNotifyMask | @@ -277,7 +277,7 @@ GHOST_WindowX11( ButtonPressMask | ButtonReleaseMask | PointerMotionMask | FocusChangeMask | PropertyChangeMask; - // create the window! + /* create the window! */ ; if (parentWindow == 0) { @@ -287,7 +287,7 @@ GHOST_WindowX11( top, width, height, - 0, // no border. + 0, /* no border. */ m_visual->depth, InputOutput, m_visual->visual, @@ -311,12 +311,12 @@ GHOST_WindowX11( m_window = XCreateWindow(m_display, - parentWindow, // reparent against embedder + parentWindow, /* reparent against embedder */ left, top, width, height, - 0, // no border. + 0, /* no border. */ m_visual->depth, InputOutput, m_visual->visual, @@ -353,9 +353,9 @@ GHOST_WindowX11( m_post_init = False; m_post_state = GHOST_kWindowStateNormal; } - - // Create some hints for the window manager on how - // we want this window treated. + + /* Create some hints for the window manager on how + * we want this window treated. */ XSizeHints *xsizehints = XAllocSizeHints(); xsizehints->flags = PPosition | PSize | PMinSize | PMaxSize; @@ -363,8 +363,8 @@ GHOST_WindowX11( xsizehints->y = top; xsizehints->width = width; xsizehints->height = height; - xsizehints->min_width = 320; // size hints, could be made apart of the ghost api - xsizehints->min_height = 240; // limits are also arbitrary, but should not allow 1x1 window + xsizehints->min_width = 320; /* size hints, could be made apart of the ghost api */ + xsizehints->min_height = 240; /* limits are also arbitrary, but should not allow 1x1 window */ xsizehints->max_width = 65535; xsizehints->max_height = 65535; XSetWMNormalHints(m_display, m_window, xsizehints); @@ -404,7 +404,7 @@ GHOST_WindowX11( m_xic = NULL; #endif - // Set the window icon + /* Set the window icon */ XWMHints *xwmhints = XAllocWMHints(); XImage *x_image, *mask_image; Pixmap icon_pixmap, mask_pixmap; @@ -442,7 +442,7 @@ GHOST_WindowX11( XPutImage(display, icon_pixmap, gc_icon, x_image, 0, 0, 0, 0, BLENDER_ICON_WIDTH, BLENDER_ICON_HEIGHT); XPutImage(display, mask_pixmap, gc_mask, mask_image, 0, 0, 0, 0, BLENDER_ICON_WIDTH, BLENDER_ICON_HEIGHT); - // Now the pixmap is ok to assign to the window as a hint + /* Now the pixmap is ok to assign to the window as a hint */ xwmhints->icon_pixmap = icon_pixmap; xwmhints->icon_mask = mask_pixmap; XFreeGC(display, gc_icon); @@ -455,7 +455,7 @@ GHOST_WindowX11( xwmhints->flags = InputHint | IconPixmapHint | IconMaskHint | StateHint; XSetWMHints(display, m_window, xwmhints); XFree(xwmhints); - // done setting the icon + /* done setting the icon */ setTitle(title); @@ -463,7 +463,7 @@ GHOST_WindowX11( initXInputDevices(); #endif - // now set up the rendering context. + /* now set up the rendering context. */ if (installDrawingContext(type) == GHOST_kSuccess) { m_valid_setup = true; GHOST_PRINT("Created window\n"); @@ -748,8 +748,8 @@ setTitle( (const unsigned char *) title.ReadPtr(), title.Length()); -// This should convert to valid x11 string -// and getTitle would need matching change + /* This should convert to valid x11 string + * and getTitle would need matching change */ XStoreName(m_display, m_window, title); XFlush(m_display); @@ -772,8 +772,8 @@ GHOST_WindowX11:: getWindowBounds( GHOST_Rect& bounds) const { - // Getting the window bounds under X11 is not - // really supported (nor should it be desired). + /* Getting the window bounds under X11 is not + * really supported (nor should it be desired). */ getClientBounds(bounds); } @@ -848,7 +848,7 @@ screenToClient( GHOST_TInt32& outX, GHOST_TInt32& outY) const { - // This is correct! + /* This is correct! */ int ax, ay; Window temp; @@ -1274,18 +1274,18 @@ GHOST_TSuccess GHOST_WindowX11:: invalidate() { - // So the idea of this function is to generate an expose event - // for the window. - // Unfortunately X does not handle expose events for you and - // it is the client's job to refresh the dirty part of the window. - // We need to queue up invalidate calls and generate GHOST events - // for them in the system. - - // We implement this by setting a boolean in this class to concatenate - // all such calls into a single event for this window. - - // At the same time we queue the dirty windows in the system class - // and generate events for them at the next processEvents call. + /* So the idea of this function is to generate an expose event + * for the window. + * Unfortunately X does not handle expose events for you and + * it is the client's job to refresh the dirty part of the window. + * We need to queue up invalidate calls and generate GHOST events + * for them in the system. + * + * We implement this by setting a boolean in this class to concatenate + * all such calls into a single event for this window. + * + * At the same time we queue the dirty windows in the system class + * and generate events for them at the next processEvents call. */ if (m_invalid_window == false) { m_system->addDirtyWindow(this); @@ -1384,7 +1384,7 @@ GHOST_WindowX11:: installDrawingContext( GHOST_TDrawingContextType type) { - // only support openGL for now. + /* only support openGL for now. */ GHOST_TSuccess success; switch (type) { case GHOST_kDrawingContextTypeOpenGL: diff --git a/intern/guardedalloc/MEM_guardedalloc.h b/intern/guardedalloc/MEM_guardedalloc.h index 65ce7baba1e..ae8115a337e 100644 --- a/intern/guardedalloc/MEM_guardedalloc.h +++ b/intern/guardedalloc/MEM_guardedalloc.h @@ -63,6 +63,9 @@ #include <stdio.h> /* needed for FILE* */ #include "MEM_sys_types.h" /* needed for uintptr_t */ +/* some GNU attributes are only available from GCC 4.3 */ +#define MEM_GNU_ATTRIBUTES (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 403)) + #ifdef __cplusplus extern "C" { #endif @@ -71,7 +74,7 @@ extern "C" { * by vmemh. If the pointer was not previously allocated by this * module, the result is undefined.*/ size_t MEM_allocN_len(const void *vmemh) -#ifdef __GNUC__ +#if MEM_GNU_ATTRIBUTES __attribute__((warn_unused_result)) #endif ; @@ -90,7 +93,7 @@ extern "C" { * Duplicates a block of memory, and returns a pointer to the * newly allocated block. */ void *MEM_dupallocN(void *vmemh) -#ifdef __GNUC__ +#if MEM_GNU_ATTRIBUTES __attribute__((warn_unused_result)) #endif ; @@ -101,7 +104,7 @@ extern "C" { * as a system realloc but just makes a new allocation and copies * over from existing memory. */ void *MEM_reallocN(void *vmemh, size_t len) -#ifdef __GNUC__ +#if MEM_GNU_ATTRIBUTES __attribute__((warn_unused_result)) __attribute__((alloc_size(2))) #endif @@ -112,7 +115,7 @@ extern "C" { * memory is cleared. The name must be static, because only a * pointer to it is stored ! */ void *MEM_callocN(size_t len, const char *str) -#ifdef __GNUC__ +#if MEM_GNU_ATTRIBUTES __attribute__((warn_unused_result)) __attribute__((nonnull(2))) __attribute__((alloc_size(1))) @@ -124,7 +127,7 @@ extern "C" { * name must be a static, because only a pointer to it is stored ! * */ void *MEM_mallocN(size_t len, const char *str) -#ifdef __GNUC__ +#if MEM_GNU_ATTRIBUTES __attribute__((warn_unused_result)) __attribute__((nonnull(2))) __attribute__((alloc_size(1))) @@ -136,7 +139,7 @@ extern "C" { * Can be free'd with MEM_freeN as usual. * */ void *MEM_mapallocN(size_t len, const char *str) -#ifdef __GNUC__ +#if MEM_GNU_ATTRIBUTES __attribute__((warn_unused_result)) __attribute__((nonnull(2))) __attribute__((alloc_size(1))) @@ -188,7 +191,7 @@ extern "C" { /** Get the peak memory usage in bytes, including mmap allocations. */ uintptr_t MEM_get_peak_memory(void) -#ifdef __GNUC__ +#if MEM_GNU_ATTRIBUTES __attribute__((warn_unused_result)) #endif ; diff --git a/intern/guardedalloc/intern/mallocn.c b/intern/guardedalloc/intern/mallocn.c index 76df58f4a50..c4902e6aa5a 100644 --- a/intern/guardedalloc/intern/mallocn.c +++ b/intern/guardedalloc/intern/mallocn.c @@ -55,6 +55,14 @@ #include "MEM_guardedalloc.h" /* Only for debugging: + * store original buffer's name when doing MEM_dupallocN + * helpful to profile issues with non-freed "dup_alloc" buffers, + * but this introduces some overhead to memory header and makes + * things slower a bit, so betterto keep disabled by default + */ +//#define DEBUG_MEMDUPLINAME + +/* Only for debugging: * lets you count the allocations so as to find the allocator of unfreed memory * in situations where the leak is predictable */ @@ -96,6 +104,10 @@ typedef struct MemHead { #ifdef DEBUG_MEMCOUNTER int _count; #endif + +#ifdef DEBUG_MEMDUPLINAME + int need_free_name, pad; +#endif } MemHead; typedef struct MemTail { @@ -243,13 +255,36 @@ void *MEM_dupallocN(void *vmemh) if (vmemh) { MemHead *memh = vmemh; memh--; - + +#ifndef DEBUG_MEMDUPLINAME if (memh->mmap) newp = MEM_mapallocN(memh->len, "dupli_mapalloc"); else newp = MEM_mallocN(memh->len, "dupli_alloc"); if (newp == NULL) return NULL; +#else + { + MemHead *nmemh; + char *name = malloc(strlen(memh->name) + 24); + + if (memh->mmap) { + sprintf(name, "%s %s", "dupli_mapalloc", memh->name); + newp = MEM_mapallocN(memh->len, name); + } + else { + sprintf(name, "%s %s", "dupli_alloc", memh->name); + newp = MEM_mallocN(memh->len, name); + } + + if (newp == NULL) return NULL; + + nmemh = newp; + nmemh--; + + nmemh->need_free_name = 1; + } +#endif memcpy(newp, vmemh, memh->len); } @@ -289,6 +324,10 @@ static void make_memhead_header(MemHead *memh, size_t len, const char *str) memh->len = len; memh->mmap = 0; memh->tag2 = MEMTAG2; + +#ifdef DEBUG_MEMDUPLINAME + memh->need_free_name = 0; +#endif memt = (MemTail *)(((char *) memh) + sizeof(MemHead) + len); memt->tag3 = MEMTAG3; @@ -605,7 +644,7 @@ void MEM_printmemlist_pydict(void) MEM_printmemlist_internal(1); } -short MEM_freeN(void *vmemh) /* anders compileertie niet meer */ +short MEM_freeN(void *vmemh) { short error = 0; MemTail *memt; @@ -733,6 +772,11 @@ static void rem_memblock(MemHead *memh) totblock--; mem_in_use -= memh->len; +#ifdef DEBUG_MEMDUPLINAME + if (memh->need_free_name) + free((char *) memh->name); +#endif + if (memh->mmap) { mmap_in_use -= memh->len; if (munmap(memh, memh->len + sizeof(MemHead) + sizeof(MemTail))) diff --git a/intern/iksolver/extern/IK_solver.h b/intern/iksolver/extern/IK_solver.h index 7f780a0a17f..a3f599e06c8 100644 --- a/intern/iksolver/extern/IK_solver.h +++ b/intern/iksolver/extern/IK_solver.h @@ -163,6 +163,9 @@ float IK_SolverGetPoleAngle(IK_Solver *solver); int IK_Solve(IK_Solver *solver, float tolerance, int max_iterations); +#define IK_STRETCH_STIFF_EPS 0.001f +#define IK_STRETCH_STIFF_MIN 0.001f +#define IK_STRETCH_STIFF_MAX 1e10 #ifdef __cplusplus } diff --git a/intern/iksolver/intern/IK_QJacobian.cpp b/intern/iksolver/intern/IK_QJacobian.cpp index e85da6eda4a..bb7b7c5c0b8 100644 --- a/intern/iksolver/intern/IK_QJacobian.cpp +++ b/intern/iksolver/intern/IK_QJacobian.cpp @@ -35,7 +35,7 @@ #include "TNT/svd.h" IK_QJacobian::IK_QJacobian() -: m_sdls(true), m_min_damp(1.0) + : m_sdls(true), m_min_damp(1.0) { } @@ -106,16 +106,16 @@ void IK_QJacobian::ArmMatrices(int dof, int task_size) void IK_QJacobian::SetBetas(int id, int, const MT_Vector3& v) { - m_beta[id] = v.x(); - m_beta[id+1] = v.y(); - m_beta[id+2] = v.z(); + m_beta[id + 0] = v.x(); + m_beta[id + 1] = v.y(); + m_beta[id + 2] = v.z(); } void IK_QJacobian::SetDerivatives(int id, int dof_id, const MT_Vector3& v, MT_Scalar norm_weight) { - m_jacobian[id][dof_id] = v.x()*m_weight_sqrt[dof_id]; - m_jacobian[id+1][dof_id] = v.y()*m_weight_sqrt[dof_id]; - m_jacobian[id+2][dof_id] = v.z()*m_weight_sqrt[dof_id]; + m_jacobian[id + 0][dof_id] = v.x() * m_weight_sqrt[dof_id]; + m_jacobian[id + 1][dof_id] = v.y() * m_weight_sqrt[dof_id]; + m_jacobian[id + 2][dof_id] = v.z() * m_weight_sqrt[dof_id]; m_d_norm_weight[dof_id] = norm_weight; } @@ -194,7 +194,7 @@ void IK_QJacobian::SubTask(IK_QJacobian& jacobian) // doesn't work well at all int i; for (i = 0; i < m_d_theta.size(); i++) - m_d_theta[i] = m_d_theta[i] + /*m_min_damp**/jacobian.AngleUpdate(i); + m_d_theta[i] = m_d_theta[i] + /*m_min_damp * */ jacobian.AngleUpdate(i); } void IK_QJacobian::Restrict(TVector& d_theta, TMatrix& null) @@ -230,7 +230,7 @@ void IK_QJacobian::InvertSDLS() // DLS. The SDLS damps individual singular values, instead of using a single // damping term. - MT_Scalar max_angle_change = MT_PI/4.0; + MT_Scalar max_angle_change = MT_PI / 4.0; MT_Scalar epsilon = 1e-10; int i, j; @@ -239,35 +239,35 @@ void IK_QJacobian::InvertSDLS() for (i = 0; i < m_dof; i++) { m_norm[i] = 0.0; - for (j = 0; j < m_task_size; j+=3) { + for (j = 0; j < m_task_size; j += 3) { MT_Scalar n = 0.0; - n += m_jacobian[j][i]*m_jacobian[j][i]; - n += m_jacobian[j+1][i]*m_jacobian[j+1][i]; - n += m_jacobian[j+2][i]*m_jacobian[j+2][i]; + n += m_jacobian[j][i] * m_jacobian[j][i]; + n += m_jacobian[j + 1][i] * m_jacobian[j + 1][i]; + n += m_jacobian[j + 2][i] * m_jacobian[j + 2][i]; m_norm[i] += sqrt(n); } } - for (i = 0; i<m_svd_w.size(); i++) { + for (i = 0; i < m_svd_w.size(); i++) { if (m_svd_w[i] <= epsilon) continue; - MT_Scalar wInv = 1.0/m_svd_w[i]; + MT_Scalar wInv = 1.0 / m_svd_w[i]; MT_Scalar alpha = 0.0; MT_Scalar N = 0.0; // compute alpha and N - for (j=0; j<m_svd_u.num_rows(); j+=3) { - alpha += m_svd_u[j][i]*m_beta[j]; - alpha += m_svd_u[j+1][i]*m_beta[j+1]; - alpha += m_svd_u[j+2][i]*m_beta[j+2]; + for (j = 0; j < m_svd_u.num_rows(); j += 3) { + alpha += m_svd_u[j][i] * m_beta[j]; + alpha += m_svd_u[j + 1][i] * m_beta[j + 1]; + alpha += m_svd_u[j + 2][i] * m_beta[j + 2]; // note: for 1 end effector, N will always be 1, since U is // orthogonal, .. so could be optimized MT_Scalar tmp; - tmp = m_svd_u[j][i]*m_svd_u[j][i]; - tmp += m_svd_u[j+1][i]*m_svd_u[j+1][i]; - tmp += m_svd_u[j+2][i]*m_svd_u[j+2][i]; + tmp = m_svd_u[j][i] * m_svd_u[j][i]; + tmp += m_svd_u[j + 1][i] * m_svd_u[j + 1][i]; + tmp += m_svd_u[j + 2][i] * m_svd_u[j + 2][i]; N += sqrt(tmp); } alpha *= wInv; @@ -278,14 +278,14 @@ void IK_QJacobian::InvertSDLS() for (j = 0; j < m_d_theta.size(); j++) { MT_Scalar v = m_svd_v[j][i]; - M += MT_abs(v)*m_norm[j]; + M += MT_abs(v) * m_norm[j]; // compute tmporary dTheta's - m_d_theta_tmp[j] = v*alpha; + m_d_theta_tmp[j] = v * alpha; // find largest absolute dTheta // multiply with weight to prevent unnecessary damping - abs_dtheta = MT_abs(m_d_theta_tmp[j])*m_weight_sqrt[j]; + abs_dtheta = MT_abs(m_d_theta_tmp[j]) * m_weight_sqrt[j]; if (abs_dtheta > max_dtheta) max_dtheta = abs_dtheta; } @@ -295,19 +295,19 @@ void IK_QJacobian::InvertSDLS() // compute damping term and damp the dTheta's MT_Scalar gamma = max_angle_change; if (N < M) - gamma *= N/M; + gamma *= N / M; - MT_Scalar damp = (gamma < max_dtheta)? gamma/max_dtheta: 1.0; + MT_Scalar damp = (gamma < max_dtheta) ? gamma / max_dtheta : 1.0; for (j = 0; j < m_d_theta.size(); j++) { // slight hack: we do 0.80*, so that if there is some oscillation, // the system can still converge (for joint limits). also, it's // better to go a little to slow than to far - MT_Scalar dofdamp = damp/m_weight[j]; + MT_Scalar dofdamp = damp / m_weight[j]; if (dofdamp > 1.0) dofdamp = 1.0; - m_d_theta[j] += 0.80*dofdamp*m_d_theta_tmp[j]; + m_d_theta[j] += 0.80 * dofdamp * m_d_theta_tmp[j]; } if (damp < m_min_damp) @@ -317,7 +317,7 @@ void IK_QJacobian::InvertSDLS() // weight + prevent from doing angle updates with angles > max_angle_change MT_Scalar max_angle = 0.0, abs_angle; - for (j = 0; j<m_dof; j++) { + for (j = 0; j < m_dof; j++) { m_d_theta[j] *= m_weight[j]; abs_angle = MT_abs(m_d_theta[j]); @@ -327,9 +327,9 @@ void IK_QJacobian::InvertSDLS() } if (max_angle > max_angle_change) { - MT_Scalar damp = (max_angle_change)/(max_angle_change + max_angle); + MT_Scalar damp = (max_angle_change) / (max_angle_change + max_angle); - for (j = 0; j<m_dof; j++) + for (j = 0; j < m_dof; j++) m_d_theta[j] *= damp; } } @@ -360,20 +360,20 @@ void IK_QJacobian::InvertDLS() int i, j; MT_Scalar w_min = MT_INFINITY; - for (i = 0; i <m_svd_w.size() ; i++) { + for (i = 0; i < m_svd_w.size(); i++) { if (m_svd_w[i] > epsilon && m_svd_w[i] < w_min) w_min = m_svd_w[i]; } // compute lambda damping term - MT_Scalar d = x_length/max_angle_change; + MT_Scalar d = x_length / max_angle_change; MT_Scalar lambda; - if (w_min <= d/2) - lambda = d/2; + if (w_min <= d / 2) + lambda = d / 2; else if (w_min < d) - lambda = sqrt(w_min*(d - w_min)); + lambda = sqrt(w_min * (d - w_min)); else lambda = 0.0; @@ -393,17 +393,17 @@ void IK_QJacobian::InvertDLS() for (i = 0; i < m_svd_w.size(); i++) { if (m_svd_w[i] > epsilon) { - MT_Scalar wInv = m_svd_w[i]/(m_svd_w[i]*m_svd_w[i] + lambda); + MT_Scalar wInv = m_svd_w[i] / (m_svd_w[i] * m_svd_w[i] + lambda); // compute V*Winv*Ut*Beta m_svd_u_beta[i] *= wInv; - for (j = 0; j<m_d_theta.size(); j++) - m_d_theta[j] += m_svd_v[j][i]*m_svd_u_beta[i]; + for (j = 0; j < m_d_theta.size(); j++) + m_d_theta[j] += m_svd_v[j][i] * m_svd_u_beta[i]; } } - for (j = 0; j<m_d_theta.size(); j++) + for (j = 0; j < m_d_theta.size(); j++) m_d_theta[j] *= m_weight[j]; } @@ -412,7 +412,7 @@ void IK_QJacobian::Lock(int dof_id, MT_Scalar delta) int i; for (i = 0; i < m_task_size; i++) { - m_beta[i] -= m_jacobian[i][dof_id]*delta; + m_beta[i] -= m_jacobian[i][dof_id] * delta; m_jacobian[i][dof_id] = 0.0; } @@ -431,7 +431,7 @@ MT_Scalar IK_QJacobian::AngleUpdateNorm() const MT_Scalar mx = 0.0, dtheta_abs; for (i = 0; i < m_d_theta.size(); i++) { - dtheta_abs = MT_abs(m_d_theta[i]*m_d_norm_weight[i]); + dtheta_abs = MT_abs(m_d_theta[i] * m_d_norm_weight[i]); if (dtheta_abs > mx) mx = dtheta_abs; } diff --git a/intern/iksolver/intern/IK_QJacobianSolver.cpp b/intern/iksolver/intern/IK_QJacobianSolver.cpp index fe5ecf8abe3..43d177d0651 100644 --- a/intern/iksolver/intern/IK_QJacobianSolver.cpp +++ b/intern/iksolver/intern/IK_QJacobianSolver.cpp @@ -45,22 +45,22 @@ IK_QJacobianSolver::IK_QJacobianSolver() MT_Scalar IK_QJacobianSolver::ComputeScale() { - std::vector<IK_QSegment*>::iterator seg; - float length = 0.0f; + std::vector<IK_QSegment *>::iterator seg; + MT_Scalar length = 0.0f; for (seg = m_segments.begin(); seg != m_segments.end(); seg++) length += (*seg)->MaxExtension(); - if(length == 0.0f) - return 1.0f; + if (length == 0.0) + return 1.0; else - return 1.0f/length; + return 1.0 / length; } -void IK_QJacobianSolver::Scale(float scale, std::list<IK_QTask*>& tasks) +void IK_QJacobianSolver::Scale(MT_Scalar scale, std::list<IK_QTask *>& tasks) { - std::list<IK_QTask*>::iterator task; - std::vector<IK_QSegment*>::iterator seg; + std::list<IK_QTask *>::iterator task; + std::vector<IK_QSegment *>::iterator seg; for (task = tasks.begin(); task != tasks.end(); task++) (*task)->Scale(scale); @@ -82,13 +82,13 @@ void IK_QJacobianSolver::AddSegmentList(IK_QSegment *seg) AddSegmentList(child); } -bool IK_QJacobianSolver::Setup(IK_QSegment *root, std::list<IK_QTask*>& tasks) +bool IK_QJacobianSolver::Setup(IK_QSegment *root, std::list<IK_QTask *>& tasks) { m_segments.clear(); AddSegmentList(root); // assign each segment a unique id for the jacobian - std::vector<IK_QSegment*>::iterator seg; + std::vector<IK_QSegment *>::iterator seg; int num_dof = 0; for (seg = m_segments.begin(); seg != m_segments.end(); seg++) { @@ -103,7 +103,7 @@ bool IK_QJacobianSolver::Setup(IK_QSegment *root, std::list<IK_QTask*>& tasks) int primary_size = 0, primary = 0; int secondary_size = 0, secondary = 0; MT_Scalar primary_weight = 0.0, secondary_weight = 0.0; - std::list<IK_QTask*>::iterator task; + std::list<IK_QTask *>::iterator task; for (task = tasks.begin(); task != tasks.end(); task++) { IK_QTask *qtask = *task; @@ -128,20 +128,20 @@ bool IK_QJacobianSolver::Setup(IK_QSegment *root, std::list<IK_QTask*>& tasks) m_secondary_enabled = (secondary > 0); // rescale weights of tasks to sum up to 1 - MT_Scalar primary_rescale = 1.0/primary_weight; + MT_Scalar primary_rescale = 1.0 / primary_weight; MT_Scalar secondary_rescale; if (MT_fuzzyZero(secondary_weight)) secondary_rescale = 0.0; else - secondary_rescale = 1.0/secondary_weight; + secondary_rescale = 1.0 / secondary_weight; for (task = tasks.begin(); task != tasks.end(); task++) { IK_QTask *qtask = *task; if (qtask->Primary()) - qtask->SetWeight(qtask->Weight()*primary_rescale); + qtask->SetWeight(qtask->Weight() * primary_rescale); else - qtask->SetWeight(qtask->Weight()*secondary_rescale); + qtask->SetWeight(qtask->Weight() * secondary_rescale); } // set matrix sizes @@ -154,7 +154,7 @@ bool IK_QJacobianSolver::Setup(IK_QSegment *root, std::list<IK_QTask*>& tasks) for (seg = m_segments.begin(); seg != m_segments.end(); seg++) for (i = 0; i < (*seg)->NumberOfDoF(); i++) - m_jacobian.SetDoFWeight((*seg)->DoFId()+i, (*seg)->Weight(i)); + m_jacobian.SetDoFWeight((*seg)->DoFId() + i, (*seg)->Weight(i)); return true; } @@ -165,15 +165,15 @@ void IK_QJacobianSolver::SetPoleVectorConstraint(IK_QSegment *tip, MT_Vector3& g m_poletip = tip; m_goal = goal; m_polegoal = polegoal; - m_poleangle = (getangle)? 0.0f: poleangle; + m_poleangle = (getangle) ? 0.0f : poleangle; m_getpoleangle = getangle; } static MT_Scalar safe_acos(MT_Scalar f) { // acos that does not return NaN with rounding errors - if (f <= -1.0f) return MT_PI; - else if (f >= 1.0f) return 0.0; + if (f <= -1.0) return MT_PI; + else if (f >= 1.0) return 0.0; else return acos(f); } @@ -182,7 +182,7 @@ static MT_Vector3 normalize(const MT_Vector3& v) // a sane normalize function that doesn't give (1, 0, 0) in case // of a zero length vector, like MT_Vector3.normalize MT_Scalar len = v.length(); - return MT_fuzzyZero(len)? MT_Vector3(0, 0, 0): v/len; + return MT_fuzzyZero(len) ? MT_Vector3(0, 0, 0) : v / len; } static float angle(const MT_Vector3& v1, const MT_Vector3& v2) @@ -190,21 +190,21 @@ static float angle(const MT_Vector3& v1, const MT_Vector3& v2) return safe_acos(v1.dot(v2)); } -void IK_QJacobianSolver::ConstrainPoleVector(IK_QSegment *root, std::list<IK_QTask*>& tasks) +void IK_QJacobianSolver::ConstrainPoleVector(IK_QSegment *root, std::list<IK_QTask *>& tasks) { // this function will be called before and after solving. calling it before // solving gives predictable solutions by rotating towards the solution, // and calling it afterwards ensures the solution is exact. - if(!m_poleconstraint) + if (!m_poleconstraint) return; // disable pole vector constraint in case of multiple position tasks - std::list<IK_QTask*>::iterator task; + std::list<IK_QTask *>::iterator task; int positiontasks = 0; for (task = tasks.begin(); task != tasks.end(); task++) - if((*task)->PositionTask()) + if ((*task)->PositionTask()) positiontasks++; if (positiontasks >= 2) { @@ -223,12 +223,12 @@ void IK_QJacobianSolver::ConstrainPoleVector(IK_QSegment *root, std::list<IK_QTa // an up vector, with the direction going from the root to the end effector // and the up vector going from the root to the pole constraint position. MT_Vector3 dir = normalize(endpos - rootpos); - MT_Vector3 rootx= rootbasis.getColumn(0); - MT_Vector3 rootz= rootbasis.getColumn(2); - MT_Vector3 up = rootx*cos(m_poleangle) + rootz*sin(m_poleangle); + MT_Vector3 rootx = rootbasis.getColumn(0); + MT_Vector3 rootz = rootbasis.getColumn(2); + MT_Vector3 up = rootx * cos(m_poleangle) + rootz *sin(m_poleangle); // in post, don't rotate towards the goal but only correct the pole up - MT_Vector3 poledir = (m_getpoleangle)? dir: normalize(m_goal - rootpos); + MT_Vector3 poledir = (m_getpoleangle) ? dir : normalize(m_goal - rootpos); MT_Vector3 poleup = normalize(m_polegoal - rootpos); MT_Matrix3x3 mat, polemat; @@ -241,11 +241,11 @@ void IK_QJacobianSolver::ConstrainPoleVector(IK_QSegment *root, std::list<IK_QTa polemat[1] = MT_cross(polemat[0], poledir); polemat[2] = -poledir; - if(m_getpoleangle) { + if (m_getpoleangle) { // we compute the pole angle that to rotate towards the target m_poleangle = angle(mat[1], polemat[1]); - if(rootz.dot(mat[1]*cos(m_poleangle) + mat[0]*sin(m_poleangle)) > 0.0f) + if (rootz.dot(mat[1] * cos(m_poleangle) + mat[0] * sin(m_poleangle)) > 0.0) m_poleangle = -m_poleangle; // solve again, with the pole angle we just computed @@ -257,15 +257,15 @@ void IK_QJacobianSolver::ConstrainPoleVector(IK_QSegment *root, std::list<IK_QTa // desired rotation based on the pole vector constraint. we use // transpose instead of inverse because we have orthogonal matrices // anyway, and in case of a singular matrix we don't get NaN's. - MT_Transform trans(MT_Point3(0, 0, 0), polemat.transposed()*mat); - m_rootmatrix = trans*m_rootmatrix; + MT_Transform trans(MT_Point3(0, 0, 0), polemat.transposed() * mat); + m_rootmatrix = trans * m_rootmatrix; } } bool IK_QJacobianSolver::UpdateAngles(MT_Scalar& norm) { // assing each segment a unique id for the jacobian - std::vector<IK_QSegment*>::iterator seg; + std::vector<IK_QSegment *>::iterator seg; IK_QSegment *qseg, *minseg = NULL; MT_Scalar minabsdelta = 1e10, absdelta; MT_Vector3 delta, mindelta; @@ -318,11 +318,11 @@ bool IK_QJacobianSolver::UpdateAngles(MT_Scalar& norm) } bool IK_QJacobianSolver::Solve( - IK_QSegment *root, - std::list<IK_QTask*> tasks, - const MT_Scalar, - const int max_iterations -) + IK_QSegment *root, + std::list<IK_QTask *> tasks, + const MT_Scalar, + const int max_iterations + ) { float scale = ComputeScale(); bool solved = false; @@ -339,7 +339,7 @@ bool IK_QJacobianSolver::Solve( // update transform root->UpdateTransform(m_rootmatrix); - std::list<IK_QTask*>::iterator task; + std::list<IK_QTask *>::iterator task; // compute jacobian for (task = tasks.begin(); task != tasks.end(); task++) { @@ -367,7 +367,7 @@ bool IK_QJacobianSolver::Solve( } while (UpdateAngles(norm)); // unlock segments again after locking in clamping loop - std::vector<IK_QSegment*>::iterator seg; + std::vector<IK_QSegment *>::iterator seg; for (seg = m_segments.begin(); seg != m_segments.end(); seg++) (*seg)->UnLock(); @@ -383,10 +383,10 @@ bool IK_QJacobianSolver::Solve( } } - if(m_poleconstraint) + if (m_poleconstraint) root->PrependBasis(m_rootmatrix.getBasis()); - Scale(1.0f/scale, tasks); + Scale(1.0f / scale, tasks); //analyze_add_run(max_iterations, analyze_time()-dt); diff --git a/intern/iksolver/intern/IK_QJacobianSolver.h b/intern/iksolver/intern/IK_QJacobianSolver.h index cfcd2849fb2..ead2b150b40 100644 --- a/intern/iksolver/intern/IK_QJacobianSolver.h +++ b/intern/iksolver/intern/IK_QJacobianSolver.h @@ -77,7 +77,7 @@ private: void ConstrainPoleVector(IK_QSegment *root, std::list<IK_QTask*>& tasks); MT_Scalar ComputeScale(); - void Scale(float scale, std::list<IK_QTask*>& tasks); + void Scale(MT_Scalar scale, std::list<IK_QTask*>& tasks); private: diff --git a/intern/iksolver/intern/IK_QSegment.cpp b/intern/iksolver/intern/IK_QSegment.cpp index d81ed453037..e511d8233a2 100644 --- a/intern/iksolver/intern/IK_QSegment.cpp +++ b/intern/iksolver/intern/IK_QSegment.cpp @@ -60,24 +60,25 @@ static MT_Matrix3x3 RotationMatrix(MT_Scalar angle, int axis) static MT_Scalar EulerAngleFromMatrix(const MT_Matrix3x3& R, int axis) { - MT_Scalar t = sqrt(R[0][0]*R[0][0] + R[0][1]*R[0][1]); + MT_Scalar t = sqrt(R[0][0] * R[0][0] + R[0][1] * R[0][1]); - if (t > 16.0*MT_EPSILON) { - if (axis == 0) return -atan2(R[1][2], R[2][2]); - else if(axis == 1) return atan2(-R[0][2], t); - else return -atan2(R[0][1], R[0][0]); - } else { - if (axis == 0) return -atan2(-R[2][1], R[1][1]); - else if(axis == 1) return atan2(-R[0][2], t); - else return 0.0f; - } + if (t > 16.0 * MT_EPSILON) { + if (axis == 0) return -atan2(R[1][2], R[2][2]); + else if (axis == 1) return atan2(-R[0][2], t); + else return -atan2(R[0][1], R[0][0]); + } + else { + if (axis == 0) return -atan2(-R[2][1], R[1][1]); + else if (axis == 1) return atan2(-R[0][2], t); + else return 0.0f; + } } static MT_Scalar safe_acos(MT_Scalar f) { - if (f <= -1.0f) + if (f <= -1.0) return MT_PI; - else if (f >= 1.0f) + else if (f >= 1.0) return 0.0; else return acos(f); @@ -89,7 +90,7 @@ static MT_Scalar ComputeTwist(const MT_Matrix3x3& R) MT_Scalar qy = R[0][2] - R[2][0]; MT_Scalar qw = R[0][0] + R[1][1] + R[2][2] + 1; - MT_Scalar tau = 2*atan2(qy, qw); + MT_Scalar tau = 2.0 * atan2(qy, qw); return tau; } @@ -108,7 +109,7 @@ static void RemoveTwist(MT_Matrix3x3& R) MT_Matrix3x3 T = ComputeTwistMatrix(tau); // remove twist - R = R*T.transposed(); + R = R * T.transposed(); } static MT_Vector3 SphericalRangeParameters(const MT_Matrix3x3& R) @@ -117,7 +118,7 @@ static MT_Vector3 SphericalRangeParameters(const MT_Matrix3x3& R) MT_Scalar tau = ComputeTwist(R); // compute swing parameters - MT_Scalar num = 2.0*(1.0 + R[1][1]); + MT_Scalar num = 2.0 * (1.0 + R[1][1]); // singularity at pi if (MT_abs(num) < MT_EPSILON) @@ -126,9 +127,9 @@ static MT_Vector3 SphericalRangeParameters(const MT_Matrix3x3& R) // enforce limits at all then return MT_Vector3(0.0, tau, 1.0); - num = 1.0/sqrt(num); - MT_Scalar ax = -R[2][1]*num; - MT_Scalar az = R[0][1]*num; + num = 1.0 / sqrt(num); + MT_Scalar ax = -R[2][1] * num; + MT_Scalar az = R[0][1] * num; return MT_Vector3(ax, tau, az); } @@ -136,8 +137,8 @@ static MT_Vector3 SphericalRangeParameters(const MT_Matrix3x3& R) static MT_Matrix3x3 ComputeSwingMatrix(MT_Scalar ax, MT_Scalar az) { // length of (ax, 0, az) = sin(theta/2) - MT_Scalar sine2 = ax*ax + az*az; - MT_Scalar cosine2 = sqrt((sine2 >= 1.0)? 0.0: 1.0-sine2); + MT_Scalar sine2 = ax * ax + az * az; + MT_Scalar cosine2 = sqrt((sine2 >= 1.0) ? 0.0 : 1.0 - sine2); // compute swing matrix MT_Matrix3x3 S(MT_Quaternion(ax, 0.0, az, -cosine2)); @@ -151,11 +152,11 @@ static MT_Vector3 MatrixToAxisAngle(const MT_Matrix3x3& R) R[0][2] - R[2][0], R[1][0] - R[0][1]); - MT_Scalar c = safe_acos((R[0][0] + R[1][1] + R[2][2] - 1)/2); + MT_Scalar c = safe_acos((R[0][0] + R[1][1] + R[2][2] - 1) / 2); MT_Scalar l = delta.length(); if (!MT_fuzzyZero(l)) - delta *= c/l; + delta *= c / l; return delta; } @@ -192,10 +193,10 @@ static bool EllipseClamp(MT_Scalar& ax, MT_Scalar& az, MT_Scalar *amin, MT_Scala z = zlim; } else { - MT_Scalar invx = 1.0/(xlim*xlim); - MT_Scalar invz = 1.0/(zlim*zlim); + MT_Scalar invx = 1.0 / (xlim * xlim); + MT_Scalar invz = 1.0 / (zlim * zlim); - if ((x*x*invx + z*z*invz) <= 1.0) + if ((x * x * invx + z * z * invz) <= 1.0) return false; if (MT_fuzzyZero(x)) { @@ -203,17 +204,17 @@ static bool EllipseClamp(MT_Scalar& ax, MT_Scalar& az, MT_Scalar *amin, MT_Scala z = zlim; } else { - MT_Scalar rico = z/x; + MT_Scalar rico = z / x; MT_Scalar old_x = x; - x = sqrt(1.0/(invx + invz*rico*rico)); + x = sqrt(1.0 / (invx + invz * rico * rico)); if (old_x < 0.0) x = -x; - z = rico*x; + z = rico * x; } } - ax = (ax < 0.0)? -x: x; - az = (az < 0.0)? -z: z; + ax = (ax < 0.0) ? -x : x; + az = (az < 0.0) ? -z : z; return true; } @@ -221,8 +222,8 @@ static bool EllipseClamp(MT_Scalar& ax, MT_Scalar& az, MT_Scalar *amin, MT_Scala // IK_QSegment IK_QSegment::IK_QSegment(int num_DoF, bool translational) -: m_parent(NULL), m_child(NULL), m_sibling(NULL), m_composite(NULL), - m_num_DoF(num_DoF), m_translational(translational) + : m_parent(NULL), m_child(NULL), m_sibling(NULL), m_composite(NULL), + m_num_DoF(num_DoF), m_translational(translational) { m_locked[0] = m_locked[1] = m_locked[2] = false; m_weight[0] = m_weight[1] = m_weight[2] = 1.0; @@ -251,11 +252,11 @@ void IK_QSegment::Reset() } void IK_QSegment::SetTransform( - const MT_Vector3& start, - const MT_Matrix3x3& rest_basis, - const MT_Matrix3x3& basis, - const MT_Scalar length -) + const MT_Vector3& start, + const MT_Matrix3x3& rest_basis, + const MT_Matrix3x3& basis, + const MT_Scalar length + ) { m_max_extension = start.length() + length; @@ -271,7 +272,7 @@ void IK_QSegment::SetTransform( MT_Matrix3x3 IK_QSegment::BasisChange() const { - return m_orig_basis.transposed()*m_basis; + return m_orig_basis.transposed() * m_basis; } MT_Vector3 IK_QSegment::TranslationChange() const @@ -329,7 +330,7 @@ void IK_QSegment::RemoveChild(IK_QSegment *child) void IK_QSegment::UpdateTransform(const MT_Transform& global) { // compute the global transform at the end of the segment - m_global_start = global.getOrigin() + global.getBasis()*m_start; + m_global_start = global.getOrigin() + global.getBasis() * m_start; m_global_transform.setOrigin(m_global_start); m_global_transform.setBasis(global.getBasis() * m_rest_basis * m_basis); @@ -345,7 +346,7 @@ void IK_QSegment::PrependBasis(const MT_Matrix3x3& mat) m_basis = m_rest_basis.inverse() * mat * m_rest_basis * m_basis; } -void IK_QSegment::Scale(float scale) +void IK_QSegment::Scale(MT_Scalar scale) { m_start *= scale; m_translation *= scale; @@ -358,7 +359,7 @@ void IK_QSegment::Scale(float scale) // IK_QSphericalSegment IK_QSphericalSegment::IK_QSphericalSegment() -: IK_QSegment(3, false), m_limit_x(false), m_limit_y(false), m_limit_z(false) + : IK_QSegment(3, false), m_limit_x(false), m_limit_y(false), m_limit_z(false) { } @@ -386,8 +387,8 @@ void IK_QSphericalSegment::SetLimit(int axis, MT_Scalar lmin, MT_Scalar lmax) lmin = MT_clamp(lmin, -MT_PI, MT_PI); lmax = MT_clamp(lmax, -MT_PI, MT_PI); - lmin = sin(lmin*0.5); - lmax = sin(lmax*0.5); + lmin = sin(lmin * 0.5); + lmax = sin(lmax * 0.5); if (axis == 0) { m_min[0] = -lmax; @@ -414,8 +415,8 @@ bool IK_QSphericalSegment::UpdateAngle(const IK_QJacobian &jacobian, MT_Vector3& MT_Vector3 dq; dq.x() = jacobian.AngleUpdate(m_DoF_id); - dq.y() = jacobian.AngleUpdate(m_DoF_id+1); - dq.z() = jacobian.AngleUpdate(m_DoF_id+2); + dq.y() = jacobian.AngleUpdate(m_DoF_id + 1); + dq.z() = jacobian.AngleUpdate(m_DoF_id + 2); // Directly update the rotation matrix, with Rodrigues' rotation formula, // to avoid singularities and allow smooth integration. @@ -423,29 +424,29 @@ bool IK_QSphericalSegment::UpdateAngle(const IK_QJacobian &jacobian, MT_Vector3& MT_Scalar theta = dq.length(); if (!MT_fuzzyZero(theta)) { - MT_Vector3 w = dq*(1.0/theta); + MT_Vector3 w = dq * (1.0 / theta); MT_Scalar sine = sin(theta); MT_Scalar cosine = cos(theta); - MT_Scalar cosineInv = 1-cosine; + MT_Scalar cosineInv = 1 - cosine; - MT_Scalar xsine = w.x()*sine; - MT_Scalar ysine = w.y()*sine; - MT_Scalar zsine = w.z()*sine; + MT_Scalar xsine = w.x() * sine; + MT_Scalar ysine = w.y() * sine; + MT_Scalar zsine = w.z() * sine; - MT_Scalar xxcosine = w.x()*w.x()*cosineInv; - MT_Scalar xycosine = w.x()*w.y()*cosineInv; - MT_Scalar xzcosine = w.x()*w.z()*cosineInv; - MT_Scalar yycosine = w.y()*w.y()*cosineInv; - MT_Scalar yzcosine = w.y()*w.z()*cosineInv; - MT_Scalar zzcosine = w.z()*w.z()*cosineInv; + MT_Scalar xxcosine = w.x() * w.x() * cosineInv; + MT_Scalar xycosine = w.x() * w.y() * cosineInv; + MT_Scalar xzcosine = w.x() * w.z() * cosineInv; + MT_Scalar yycosine = w.y() * w.y() * cosineInv; + MT_Scalar yzcosine = w.y() * w.z() * cosineInv; + MT_Scalar zzcosine = w.z() * w.z() * cosineInv; MT_Matrix3x3 M( - cosine + xxcosine, -zsine + xycosine, ysine + xzcosine, - zsine + xycosine, cosine + yycosine, -xsine + yzcosine, - -ysine + xzcosine, xsine + yzcosine, cosine + zzcosine); + cosine + xxcosine, -zsine + xycosine, ysine + xzcosine, + zsine + xycosine, cosine + yycosine, -xsine + yzcosine, + -ysine + xzcosine, xsine + yzcosine, cosine + zzcosine); - m_new_basis = m_basis*M; + m_new_basis = m_basis * M; } else m_new_basis = m_basis; @@ -505,13 +506,13 @@ bool IK_QSphericalSegment::UpdateAngle(const IK_QJacobian &jacobian, MT_Vector3& if (clamp[0] == false && clamp[1] == false && clamp[2] == false) { if (m_locked[0] || m_locked[1] || m_locked[2]) - m_new_basis = ComputeSwingMatrix(ax, az)*ComputeTwistMatrix(ay); + m_new_basis = ComputeSwingMatrix(ax, az) * ComputeTwistMatrix(ay); return false; } - m_new_basis = ComputeSwingMatrix(ax, az)*ComputeTwistMatrix(ay); + m_new_basis = ComputeSwingMatrix(ax, az) * ComputeTwistMatrix(ay); - delta = MatrixToAxisAngle(m_basis.transposed()*m_new_basis); + delta = MatrixToAxisAngle(m_basis.transposed() * m_new_basis); if (!(m_locked[0] || m_locked[2]) && (clamp[0] || clamp[2])) { m_locked_ax = ax; @@ -528,12 +529,12 @@ void IK_QSphericalSegment::Lock(int dof, IK_QJacobian& jacobian, MT_Vector3& del { if (dof == 1) { m_locked[1] = true; - jacobian.Lock(m_DoF_id+1, delta[1]); + jacobian.Lock(m_DoF_id + 1, delta[1]); } else { m_locked[0] = m_locked[2] = true; jacobian.Lock(m_DoF_id, delta[0]); - jacobian.Lock(m_DoF_id+2, delta[2]); + jacobian.Lock(m_DoF_id + 2, delta[2]); } } @@ -545,14 +546,14 @@ void IK_QSphericalSegment::UpdateAngleApply() // IK_QNullSegment IK_QNullSegment::IK_QNullSegment() -: IK_QSegment(0, false) + : IK_QSegment(0, false) { } // IK_QRevoluteSegment IK_QRevoluteSegment::IK_QRevoluteSegment(int axis) -: IK_QSegment(1, false), m_axis(axis), m_angle(0.0), m_limit(false) + : IK_QSegment(1, false), m_axis(axis), m_angle(0.0), m_limit(false) { } @@ -634,7 +635,7 @@ void IK_QRevoluteSegment::SetWeight(int axis, MT_Scalar weight) // IK_QSwingSegment IK_QSwingSegment::IK_QSwingSegment() -: IK_QSegment(2, false), m_limit_x(false), m_limit_z(false) + : IK_QSegment(2, false), m_limit_x(false), m_limit_z(false) { } @@ -646,7 +647,7 @@ void IK_QSwingSegment::SetBasis(const MT_Matrix3x3& basis) MT_Vector3 IK_QSwingSegment::Axis(int dof) const { - return m_global_transform.getBasis().getColumn((dof==0)? 0: 2); + return m_global_transform.getBasis().getColumn((dof == 0) ? 0 : 2); } bool IK_QSwingSegment::UpdateAngle(const IK_QJacobian &jacobian, MT_Vector3& delta, bool *clamp) @@ -657,7 +658,7 @@ bool IK_QSwingSegment::UpdateAngle(const IK_QJacobian &jacobian, MT_Vector3& del MT_Vector3 dq; dq.x() = jacobian.AngleUpdate(m_DoF_id); dq.y() = 0.0; - dq.z() = jacobian.AngleUpdate(m_DoF_id+1); + dq.z() = jacobian.AngleUpdate(m_DoF_id + 1); // Directly update the rotation matrix, with Rodrigues' rotation formula, // to avoid singularities and allow smooth integration. @@ -665,25 +666,25 @@ bool IK_QSwingSegment::UpdateAngle(const IK_QJacobian &jacobian, MT_Vector3& del MT_Scalar theta = dq.length(); if (!MT_fuzzyZero(theta)) { - MT_Vector3 w = dq*(1.0/theta); + MT_Vector3 w = dq * (1.0 / theta); MT_Scalar sine = sin(theta); MT_Scalar cosine = cos(theta); - MT_Scalar cosineInv = 1-cosine; + MT_Scalar cosineInv = 1 - cosine; - MT_Scalar xsine = w.x()*sine; - MT_Scalar zsine = w.z()*sine; + MT_Scalar xsine = w.x() * sine; + MT_Scalar zsine = w.z() * sine; - MT_Scalar xxcosine = w.x()*w.x()*cosineInv; - MT_Scalar xzcosine = w.x()*w.z()*cosineInv; - MT_Scalar zzcosine = w.z()*w.z()*cosineInv; + MT_Scalar xxcosine = w.x() * w.x() * cosineInv; + MT_Scalar xzcosine = w.x() * w.z() * cosineInv; + MT_Scalar zzcosine = w.z() * w.z() * cosineInv; MT_Matrix3x3 M( - cosine + xxcosine, -zsine, xzcosine, - zsine, cosine, -xsine, - xzcosine, xsine, cosine + zzcosine); + cosine + xxcosine, -zsine, xzcosine, + zsine, cosine, -xsine, + xzcosine, xsine, cosine + zzcosine); - m_new_basis = m_basis*M; + m_new_basis = m_basis * M; RemoveTwist(m_new_basis); } @@ -731,7 +732,7 @@ bool IK_QSwingSegment::UpdateAngle(const IK_QJacobian &jacobian, MT_Vector3& del m_new_basis = ComputeSwingMatrix(ax, az); - delta = MatrixToAxisAngle(m_basis.transposed()*m_new_basis); + delta = MatrixToAxisAngle(m_basis.transposed() * m_new_basis); delta[1] = delta[2]; delta[2] = 0.0; return true; @@ -741,7 +742,7 @@ void IK_QSwingSegment::Lock(int, IK_QJacobian& jacobian, MT_Vector3& delta) { m_locked[0] = m_locked[1] = true; jacobian.Lock(m_DoF_id, delta[0]); - jacobian.Lock(m_DoF_id+1, delta[1]); + jacobian.Lock(m_DoF_id + 1, delta[1]); } void IK_QSwingSegment::UpdateAngleApply() @@ -758,11 +759,11 @@ void IK_QSwingSegment::SetLimit(int axis, MT_Scalar lmin, MT_Scalar lmax) lmin = MT_clamp(lmin, -MT_PI, MT_PI); lmax = MT_clamp(lmax, -MT_PI, MT_PI); - lmin = sin(lmin*0.5); - lmax = sin(lmax*0.5); + lmin = sin(lmin * 0.5); + lmax = sin(lmax * 0.5); // put center of ellispe in the middle between min and max - MT_Scalar offset = 0.5*(lmin + lmax); + MT_Scalar offset = 0.5 * (lmin + lmax); //lmax = lmax - offset; if (axis == 0) { @@ -794,8 +795,8 @@ void IK_QSwingSegment::SetWeight(int axis, MT_Scalar weight) // IK_QElbowSegment IK_QElbowSegment::IK_QElbowSegment(int axis) -: IK_QSegment(2, false), m_axis(axis), m_twist(0.0), m_angle(0.0), - m_cos_twist(1.0), m_sin_twist(0.0), m_limit(false), m_limit_twist(false) + : IK_QSegment(2, false), m_axis(axis), m_twist(0.0), m_angle(0.0), + m_cos_twist(1.0), m_sin_twist(0.0), m_limit(false), m_limit_twist(false) { } @@ -807,7 +808,7 @@ void IK_QElbowSegment::SetBasis(const MT_Matrix3x3& basis) RemoveTwist(m_basis); m_angle = EulerAngleFromMatrix(basis, m_axis); - m_basis = RotationMatrix(m_angle, m_axis)*ComputeTwistMatrix(m_twist); + m_basis = RotationMatrix(m_angle, m_axis) * ComputeTwistMatrix(m_twist); } MT_Vector3 IK_QElbowSegment::Axis(int dof) const @@ -850,7 +851,7 @@ bool IK_QElbowSegment::UpdateAngle(const IK_QJacobian &jacobian, MT_Vector3& del } if (!m_locked[1]) { - m_new_twist = m_twist + jacobian.AngleUpdate(m_DoF_id+1); + m_new_twist = m_twist + jacobian.AngleUpdate(m_DoF_id + 1); if (m_limit_twist) { if (m_new_twist > m_max_twist) { @@ -877,7 +878,7 @@ void IK_QElbowSegment::Lock(int dof, IK_QJacobian& jacobian, MT_Vector3& delta) } else { m_locked[1] = true; - jacobian.Lock(m_DoF_id+1, delta[1]); + jacobian.Lock(m_DoF_id + 1, delta[1]); } } @@ -892,7 +893,7 @@ void IK_QElbowSegment::UpdateAngleApply() MT_Matrix3x3 A = RotationMatrix(m_angle, m_axis); MT_Matrix3x3 T = RotationMatrix(m_sin_twist, m_cos_twist, 1); - m_basis = A*T; + m_basis = A * T; } void IK_QElbowSegment::SetLimit(int axis, MT_Scalar lmin, MT_Scalar lmax) @@ -927,7 +928,7 @@ void IK_QElbowSegment::SetWeight(int axis, MT_Scalar weight) // IK_QTranslateSegment IK_QTranslateSegment::IK_QTranslateSegment(int axis1) -: IK_QSegment(1, true) + : IK_QSegment(1, true) { m_axis_enabled[0] = m_axis_enabled[1] = m_axis_enabled[2] = false; m_axis_enabled[axis1] = true; @@ -938,7 +939,7 @@ IK_QTranslateSegment::IK_QTranslateSegment(int axis1) } IK_QTranslateSegment::IK_QTranslateSegment(int axis1, int axis2) -: IK_QSegment(2, true) + : IK_QSegment(2, true) { m_axis_enabled[0] = m_axis_enabled[1] = m_axis_enabled[2] = false; m_axis_enabled[axis1] = true; @@ -951,7 +952,7 @@ IK_QTranslateSegment::IK_QTranslateSegment(int axis1, int axis2) } IK_QTranslateSegment::IK_QTranslateSegment() -: IK_QSegment(3, true) + : IK_QSegment(3, true) { m_axis_enabled[0] = m_axis_enabled[1] = m_axis_enabled[2] = true; @@ -1013,7 +1014,7 @@ void IK_QTranslateSegment::UpdateAngleApply() void IK_QTranslateSegment::Lock(int dof, IK_QJacobian& jacobian, MT_Vector3& delta) { m_locked[dof] = true; - jacobian.Lock(m_DoF_id+dof, delta[dof]); + jacobian.Lock(m_DoF_id + dof, delta[dof]); } void IK_QTranslateSegment::SetWeight(int axis, MT_Scalar weight) @@ -1030,12 +1031,12 @@ void IK_QTranslateSegment::SetLimit(int axis, MT_Scalar lmin, MT_Scalar lmax) if (lmax < lmin) return; - m_min[axis]= lmin; - m_max[axis]= lmax; - m_limit[axis]= true; + m_min[axis] = lmin; + m_max[axis] = lmax; + m_limit[axis] = true; } -void IK_QTranslateSegment::Scale(float scale) +void IK_QTranslateSegment::Scale(MT_Scalar scale) { int i; diff --git a/intern/iksolver/intern/IK_QSegment.h b/intern/iksolver/intern/IK_QSegment.h index 68d40829137..25a8fbc0804 100644 --- a/intern/iksolver/intern/IK_QSegment.h +++ b/intern/iksolver/intern/IK_QSegment.h @@ -170,7 +170,7 @@ public: void Reset(); // scale - virtual void Scale(float scale); + virtual void Scale(MT_Scalar scale); protected: @@ -338,7 +338,7 @@ public: void SetWeight(int axis, MT_Scalar weight); void SetLimit(int axis, MT_Scalar lmin, MT_Scalar lmax); - void Scale(float scale); + void Scale(MT_Scalar scale); private: int m_axis[3]; diff --git a/intern/iksolver/intern/IK_QTask.cpp b/intern/iksolver/intern/IK_QTask.cpp index e050bb00658..0ba716ff59d 100644 --- a/intern/iksolver/intern/IK_QTask.cpp +++ b/intern/iksolver/intern/IK_QTask.cpp @@ -36,11 +36,11 @@ // IK_QTask IK_QTask::IK_QTask( - int size, - bool primary, - bool active, - const IK_QSegment *segment -) : + int size, + bool primary, + bool active, + const IK_QSegment *segment + ) : m_size(size), m_primary(primary), m_active(active), m_segment(segment), m_weight(1.0) { @@ -49,10 +49,10 @@ IK_QTask::IK_QTask( // IK_QPositionTask IK_QPositionTask::IK_QPositionTask( - bool primary, - const IK_QSegment *segment, - const MT_Vector3& goal -) : + bool primary, + const IK_QSegment *segment, + const MT_Vector3& goal + ) : IK_QTask(3, primary, true, segment), m_goal(goal) { // computing clamping length @@ -67,7 +67,7 @@ IK_QPositionTask::IK_QPositionTask( num++; } - m_clamp_length /= 2*num; + m_clamp_length /= 2 * num; } void IK_QPositionTask::ComputeJacobian(IK_QJacobian& jacobian) @@ -79,9 +79,9 @@ void IK_QPositionTask::ComputeJacobian(IK_QJacobian& jacobian) MT_Scalar length = d_pos.length(); if (length > m_clamp_length) - d_pos = (m_clamp_length/length)*d_pos; + d_pos = (m_clamp_length / length) * d_pos; - jacobian.SetBetas(m_id, m_size, m_weight*d_pos); + jacobian.SetBetas(m_id, m_size, m_weight * d_pos); // compute derivatives int i; @@ -91,13 +91,13 @@ void IK_QPositionTask::ComputeJacobian(IK_QJacobian& jacobian) MT_Vector3 p = seg->GlobalStart() - pos; for (i = 0; i < seg->NumberOfDoF(); i++) { - MT_Vector3 axis = seg->Axis(i)*m_weight; + MT_Vector3 axis = seg->Axis(i) * m_weight; if (seg->Translational()) - jacobian.SetDerivatives(m_id, seg->DoFId()+i, axis, 1e2); + jacobian.SetDerivatives(m_id, seg->DoFId() + i, axis, 1e2); else { MT_Vector3 pa = p.cross(axis); - jacobian.SetDerivatives(m_id, seg->DoFId()+i, pa, 1e0); + jacobian.SetDerivatives(m_id, seg->DoFId() + i, pa, 1e0); } } } @@ -113,10 +113,10 @@ MT_Scalar IK_QPositionTask::Distance() const // IK_QOrientationTask IK_QOrientationTask::IK_QOrientationTask( - bool primary, - const IK_QSegment *segment, - const MT_Matrix3x3& goal -) : + bool primary, + const IK_QSegment *segment, + const MT_Matrix3x3& goal + ) : IK_QTask(3, primary, true, segment), m_goal(goal), m_distance(0.0) { } @@ -126,17 +126,17 @@ void IK_QOrientationTask::ComputeJacobian(IK_QJacobian& jacobian) // compute betas const MT_Matrix3x3& rot = m_segment->GlobalTransform().getBasis(); - MT_Matrix3x3 d_rotm = m_goal*rot.transposed(); + MT_Matrix3x3 d_rotm = m_goal * rot.transposed(); d_rotm.transpose(); MT_Vector3 d_rot; - d_rot = -0.5*MT_Vector3(d_rotm[2][1] - d_rotm[1][2], - d_rotm[0][2] - d_rotm[2][0], - d_rotm[1][0] - d_rotm[0][1]); + d_rot = -0.5 * MT_Vector3(d_rotm[2][1] - d_rotm[1][2], + d_rotm[0][2] - d_rotm[2][0], + d_rotm[1][0] - d_rotm[0][1]); m_distance = d_rot.length(); - jacobian.SetBetas(m_id, m_size, m_weight*d_rot); + jacobian.SetBetas(m_id, m_size, m_weight * d_rot); // compute derivatives int i; @@ -146,10 +146,10 @@ void IK_QOrientationTask::ComputeJacobian(IK_QJacobian& jacobian) for (i = 0; i < seg->NumberOfDoF(); i++) { if (seg->Translational()) - jacobian.SetDerivatives(m_id, seg->DoFId()+i, MT_Vector3(0, 0, 0), 1e2); + jacobian.SetDerivatives(m_id, seg->DoFId() + i, MT_Vector3(0, 0, 0), 1e2); else { - MT_Vector3 axis = seg->Axis(i)*m_weight; - jacobian.SetDerivatives(m_id, seg->DoFId()+i, axis, 1e0); + MT_Vector3 axis = seg->Axis(i) * m_weight; + jacobian.SetDerivatives(m_id, seg->DoFId() + i, axis, 1e0); } } } @@ -158,15 +158,15 @@ void IK_QOrientationTask::ComputeJacobian(IK_QJacobian& jacobian) // Note: implementation not finished! IK_QCenterOfMassTask::IK_QCenterOfMassTask( - bool primary, - const IK_QSegment *segment, - const MT_Vector3& goal_center -) : + bool primary, + const IK_QSegment *segment, + const MT_Vector3& goal_center + ) : IK_QTask(3, primary, true, segment), m_goal_center(goal_center) { m_total_mass_inv = ComputeTotalMass(m_segment); if (!MT_fuzzyZero(m_total_mass_inv)) - m_total_mass_inv = 1.0/m_total_mass_inv; + m_total_mass_inv = 1.0 / m_total_mass_inv; } MT_Scalar IK_QCenterOfMassTask::ComputeTotalMass(const IK_QSegment *segment) @@ -182,7 +182,7 @@ MT_Scalar IK_QCenterOfMassTask::ComputeTotalMass(const IK_QSegment *segment) MT_Vector3 IK_QCenterOfMassTask::ComputeCenter(const IK_QSegment *segment) { - MT_Vector3 center = /*seg->Mass()**/segment->GlobalStart(); + MT_Vector3 center = /*seg->Mass()**/ segment->GlobalStart(); const IK_QSegment *seg; for (seg = segment->Child(); seg; seg = seg->Sibling()) @@ -197,14 +197,14 @@ void IK_QCenterOfMassTask::JacobianSegment(IK_QJacobian& jacobian, MT_Vector3& c MT_Vector3 p = center - segment->GlobalStart(); for (i = 0; i < segment->NumberOfDoF(); i++) { - MT_Vector3 axis = segment->Axis(i)*m_weight; - axis *= /*segment->Mass()**/m_total_mass_inv; + MT_Vector3 axis = segment->Axis(i) * m_weight; + axis *= /*segment->Mass()**/ m_total_mass_inv; if (segment->Translational()) - jacobian.SetDerivatives(m_id, segment->DoFId()+i, axis, 1e2); + jacobian.SetDerivatives(m_id, segment->DoFId() + i, axis, 1e2); else { MT_Vector3 pa = axis.cross(p); - jacobian.SetDerivatives(m_id, segment->DoFId()+i, pa, 1e0); + jacobian.SetDerivatives(m_id, segment->DoFId() + i, pa, 1e0); } } @@ -215,7 +215,7 @@ void IK_QCenterOfMassTask::JacobianSegment(IK_QJacobian& jacobian, MT_Vector3& c void IK_QCenterOfMassTask::ComputeJacobian(IK_QJacobian& jacobian) { - MT_Vector3 center = ComputeCenter(m_segment)*m_total_mass_inv; + MT_Vector3 center = ComputeCenter(m_segment) * m_total_mass_inv; // compute beta MT_Vector3 d_pos = m_goal_center - center; @@ -224,10 +224,10 @@ void IK_QCenterOfMassTask::ComputeJacobian(IK_QJacobian& jacobian) #if 0 if (m_distance > m_clamp_length) - d_pos = (m_clamp_length/m_distance)*d_pos; + d_pos = (m_clamp_length / m_distance) * d_pos; #endif - jacobian.SetBetas(m_id, m_size, m_weight*d_pos); + jacobian.SetBetas(m_id, m_size, m_weight * d_pos); // compute derivatives JacobianSegment(jacobian, center, m_segment); diff --git a/intern/iksolver/intern/IK_QTask.h b/intern/iksolver/intern/IK_QTask.h index 3d968cdfe38..45b1e59e606 100644 --- a/intern/iksolver/intern/IK_QTask.h +++ b/intern/iksolver/intern/IK_QTask.h @@ -78,7 +78,7 @@ public: virtual bool PositionTask() const { return false; } - virtual void Scale(float) {} + virtual void Scale(MT_Scalar) {} protected: int m_id; @@ -103,7 +103,7 @@ public: MT_Scalar Distance() const; bool PositionTask() const { return true; } - void Scale(float scale) { m_goal *= scale; m_clamp_length *= scale; } + void Scale(MT_Scalar scale) { m_goal *= scale; m_clamp_length *= scale; } private: MT_Vector3 m_goal; @@ -141,7 +141,7 @@ public: MT_Scalar Distance() const; - void Scale(float scale) { m_goal_center *= scale; m_distance *= scale; } + void Scale(MT_Scalar scale) { m_goal_center *= scale; m_distance *= scale; } private: MT_Scalar ComputeTotalMass(const IK_QSegment *segment); diff --git a/intern/iksolver/intern/IK_Solver.cpp b/intern/iksolver/intern/IK_Solver.cpp index 3876f26362c..6c2e30932bb 100644 --- a/intern/iksolver/intern/IK_Solver.cpp +++ b/intern/iksolver/intern/IK_Solver.cpp @@ -42,20 +42,21 @@ using namespace std; class IK_QSolver { public: - IK_QSolver() : root(NULL) {}; + IK_QSolver() : root(NULL) { + }; IK_QJacobianSolver solver; IK_QSegment *root; - std::list<IK_QTask*> tasks; + std::list<IK_QTask *> tasks; }; // FIXME: locks still result in small "residual" changes to the locked axes... IK_QSegment *CreateSegment(int flag, bool translate) { int ndof = 0; - ndof += (flag & IK_XDOF)? 1: 0; - ndof += (flag & IK_YDOF)? 1: 0; - ndof += (flag & IK_ZDOF)? 1: 0; + ndof += (flag & IK_XDOF) ? 1 : 0; + ndof += (flag & IK_YDOF) ? 1 : 0; + ndof += (flag & IK_ZDOF) ? 1 : 0; IK_QSegment *seg; @@ -78,7 +79,7 @@ IK_QSegment *CreateSegment(int flag, bool translate) if (flag & IK_XDOF) { axis1 = 0; - axis2 = (flag & IK_YDOF)? 1: 2; + axis2 = (flag & IK_YDOF) ? 1 : 2; } else { axis1 = 1; @@ -91,7 +92,7 @@ IK_QSegment *CreateSegment(int flag, bool translate) if (axis1 + axis2 == 2) seg = new IK_QSwingSegment(); else - seg = new IK_QElbowSegment((axis1 == 0)? 0: 2); + seg = new IK_QElbowSegment((axis1 == 0) ? 0 : 2); } } else { @@ -131,7 +132,7 @@ IK_Segment *IK_CreateSegment(int flag) void IK_FreeSegment(IK_Segment *seg) { - IK_QSegment *qseg = (IK_QSegment*)seg; + IK_QSegment *qseg = (IK_QSegment *)seg; if (qseg->Composite()) delete qseg->Composite(); @@ -140,8 +141,8 @@ void IK_FreeSegment(IK_Segment *seg) void IK_SetParent(IK_Segment *seg, IK_Segment *parent) { - IK_QSegment *qseg = (IK_QSegment*)seg; - IK_QSegment *qparent = (IK_QSegment*)parent; + IK_QSegment *qseg = (IK_QSegment *)seg; + IK_QSegment *qparent = (IK_QSegment *)parent; if (qparent && qparent->Composite()) qseg->SetParent(qparent->Composite()); @@ -151,7 +152,7 @@ void IK_SetParent(IK_Segment *seg, IK_Segment *parent) void IK_SetTransform(IK_Segment *seg, float start[3], float rest[][3], float basis[][3], float length) { - IK_QSegment *qseg = (IK_QSegment*)seg; + IK_QSegment *qseg = (IK_QSegment *)seg; MT_Vector3 mstart(start); // convert from blender column major to moto row major @@ -177,19 +178,19 @@ void IK_SetTransform(IK_Segment *seg, float start[3], float rest[][3], float bas void IK_SetLimit(IK_Segment *seg, IK_SegmentAxis axis, float lmin, float lmax) { - IK_QSegment *qseg = (IK_QSegment*)seg; + IK_QSegment *qseg = (IK_QSegment *)seg; if (axis >= IK_TRANS_X) { - if(!qseg->Translational()) { - if(qseg->Composite() && qseg->Composite()->Translational()) + if (!qseg->Translational()) { + if (qseg->Composite() && qseg->Composite()->Translational()) qseg = qseg->Composite(); else return; } - if(axis == IK_TRANS_X) axis = IK_X; - else if(axis == IK_TRANS_Y) axis = IK_Y; - else axis = IK_Z; + if (axis == IK_TRANS_X) axis = IK_X; + else if (axis == IK_TRANS_Y) axis = IK_Y; + else axis = IK_Z; } qseg->SetLimit(axis, lmin, lmax); @@ -197,25 +198,25 @@ void IK_SetLimit(IK_Segment *seg, IK_SegmentAxis axis, float lmin, float lmax) void IK_SetStiffness(IK_Segment *seg, IK_SegmentAxis axis, float stiffness) { - if (stiffness < 0.0) + if (stiffness < 0.0f) return; - if (stiffness > 0.999) - stiffness = 0.999; + if (stiffness > (1.0 - IK_STRETCH_STIFF_EPS)) + stiffness = (1.0 - IK_STRETCH_STIFF_EPS); - IK_QSegment *qseg = (IK_QSegment*)seg; - MT_Scalar weight = 1.0-stiffness; + IK_QSegment *qseg = (IK_QSegment *)seg; + MT_Scalar weight = 1.0f - stiffness; if (axis >= IK_TRANS_X) { - if(!qseg->Translational()) { - if(qseg->Composite() && qseg->Composite()->Translational()) + if (!qseg->Translational()) { + if (qseg->Composite() && qseg->Composite()->Translational()) qseg = qseg->Composite(); else return; } - if(axis == IK_TRANS_X) axis = IK_X; - else if(axis == IK_TRANS_Y) axis = IK_Y; + if (axis == IK_TRANS_X) axis = IK_X; + else if (axis == IK_TRANS_Y) axis = IK_Y; else axis = IK_Z; } @@ -224,7 +225,7 @@ void IK_SetStiffness(IK_Segment *seg, IK_SegmentAxis axis, float stiffness) void IK_GetBasisChange(IK_Segment *seg, float basis_change[][3]) { - IK_QSegment *qseg = (IK_QSegment*)seg; + IK_QSegment *qseg = (IK_QSegment *)seg; if (qseg->Translational() && qseg->Composite()) qseg = qseg->Composite(); @@ -245,7 +246,7 @@ void IK_GetBasisChange(IK_Segment *seg, float basis_change[][3]) void IK_GetTranslationChange(IK_Segment *seg, float *translation_change) { - IK_QSegment *qseg = (IK_QSegment*)seg; + IK_QSegment *qseg = (IK_QSegment *)seg; if (!qseg->Translational() && qseg->Composite()) qseg = qseg->Composite(); @@ -263,9 +264,9 @@ IK_Solver *IK_CreateSolver(IK_Segment *root) return NULL; IK_QSolver *solver = new IK_QSolver(); - solver->root = (IK_QSegment*)root; + solver->root = (IK_QSegment *)root; - return (IK_Solver*)solver; + return (IK_Solver *)solver; } void IK_FreeSolver(IK_Solver *solver) @@ -273,9 +274,9 @@ void IK_FreeSolver(IK_Solver *solver) if (solver == NULL) return; - IK_QSolver *qsolver = (IK_QSolver*)solver; - std::list<IK_QTask*>& tasks = qsolver->tasks; - std::list<IK_QTask*>::iterator task; + IK_QSolver *qsolver = (IK_QSolver *)solver; + std::list<IK_QTask *>& tasks = qsolver->tasks; + std::list<IK_QTask *>::iterator task; for (task = tasks.begin(); task != tasks.end(); task++) delete (*task); @@ -288,8 +289,8 @@ void IK_SolverAddGoal(IK_Solver *solver, IK_Segment *tip, float goal[3], float w if (solver == NULL || tip == NULL) return; - IK_QSolver *qsolver = (IK_QSolver*)solver; - IK_QSegment *qtip = (IK_QSegment*)tip; + IK_QSolver *qsolver = (IK_QSolver *)solver; + IK_QSegment *qtip = (IK_QSegment *)tip; if (qtip->Composite()) qtip = qtip->Composite(); @@ -306,8 +307,8 @@ void IK_SolverAddGoalOrientation(IK_Solver *solver, IK_Segment *tip, float goal[ if (solver == NULL || tip == NULL) return; - IK_QSolver *qsolver = (IK_QSolver*)solver; - IK_QSegment *qtip = (IK_QSegment*)tip; + IK_QSolver *qsolver = (IK_QSolver *)solver; + IK_QSegment *qtip = (IK_QSegment *)tip; if (qtip->Composite()) qtip = qtip->Composite(); @@ -327,14 +328,14 @@ void IK_SolverSetPoleVectorConstraint(IK_Solver *solver, IK_Segment *tip, float if (solver == NULL || tip == NULL) return; - IK_QSolver *qsolver = (IK_QSolver*)solver; - IK_QSegment *qtip = (IK_QSegment*)tip; + IK_QSolver *qsolver = (IK_QSolver *)solver; + IK_QSegment *qtip = (IK_QSegment *)tip; MT_Vector3 qgoal(goal); MT_Vector3 qpolegoal(polegoal); qsolver->solver.SetPoleVectorConstraint( - qtip, qgoal, qpolegoal, poleangle, getangle); + qtip, qgoal, qpolegoal, poleangle, getangle); } float IK_SolverGetPoleAngle(IK_Solver *solver) @@ -342,7 +343,7 @@ float IK_SolverGetPoleAngle(IK_Solver *solver) if (solver == NULL) return 0.0f; - IK_QSolver *qsolver = (IK_QSolver*)solver; + IK_QSolver *qsolver = (IK_QSolver *)solver; return qsolver->solver.GetPoleAngle(); } @@ -352,8 +353,8 @@ void IK_SolverAddCenterOfMass(IK_Solver *solver, IK_Segment *root, float goal[3] if (solver == NULL || root == NULL) return; - IK_QSolver *qsolver = (IK_QSolver*)solver; - IK_QSegment *qroot = (IK_QSegment*)root; + IK_QSolver *qsolver = (IK_QSolver *)solver; + IK_QSegment *qroot = (IK_QSegment *)root; // convert from blender column major to moto row major MT_Vector3 center(goal); @@ -368,18 +369,18 @@ int IK_Solve(IK_Solver *solver, float tolerance, int max_iterations) if (solver == NULL) return 0; - IK_QSolver *qsolver = (IK_QSolver*)solver; + IK_QSolver *qsolver = (IK_QSolver *)solver; IK_QSegment *root = qsolver->root; IK_QJacobianSolver& jacobian = qsolver->solver; - std::list<IK_QTask*>& tasks = qsolver->tasks; + std::list<IK_QTask *>& tasks = qsolver->tasks; MT_Scalar tol = tolerance; - if(!jacobian.Setup(root, tasks)) + if (!jacobian.Setup(root, tasks)) return 0; bool result = jacobian.Solve(root, tasks, tol, max_iterations); - return ((result)? 1: 0); + return ((result) ? 1 : 0); } diff --git a/intern/iksolver/intern/MT_ExpMap.cpp b/intern/iksolver/intern/MT_ExpMap.cpp index c997d434861..b2b13acebeb 100644 --- a/intern/iksolver/intern/MT_ExpMap.cpp +++ b/intern/iksolver/intern/MT_ExpMap.cpp @@ -37,11 +37,11 @@ * Set the exponential map from a quaternion. The quaternion must be non-zero. */ - void +void MT_ExpMap:: setRotation( - const MT_Quaternion &q -) { + const MT_Quaternion &q) +{ // ok first normalize the quaternion // then compute theta the axis-angle and the normalized axis v // scale v by theta and that's it hopefully! @@ -53,7 +53,7 @@ setRotation( m_sinp = m_v.length(); m_v /= m_sinp; - m_theta = atan2(double(m_sinp),double(cosp)); + m_theta = atan2(double(m_sinp), double(cosp)); m_v *= m_theta; } @@ -62,10 +62,10 @@ setRotation( * representation */ - const MT_Quaternion& +const MT_Quaternion& MT_ExpMap:: -getRotation( -) const { +getRotation() const +{ return m_q; } @@ -73,10 +73,10 @@ getRotation( * Convert the exponential map to a 3x3 matrix */ - MT_Matrix3x3 +MT_Matrix3x3 MT_ExpMap:: -getMatrix( -) const { +getMatrix() const +{ return MT_Matrix3x3(m_q); } @@ -84,11 +84,11 @@ getMatrix( * Update & reparameterizate the exponential map */ - void +void MT_ExpMap:: update( - const MT_Vector3& dv -){ + const MT_Vector3& dv) +{ m_v += dv; angleUpdated(); @@ -100,14 +100,13 @@ update( * from the map) and return them as a 3x3 matrix */ - void +void MT_ExpMap:: partialDerivatives( - MT_Matrix3x3& dRdx, - MT_Matrix3x3& dRdy, - MT_Matrix3x3& dRdz -) const { - + MT_Matrix3x3& dRdx, + MT_Matrix3x3& dRdy, + MT_Matrix3x3& dRdz) const +{ MT_Quaternion dQdx[3]; compute_dQdVi(dQdx); @@ -117,29 +116,28 @@ partialDerivatives( compute_dRdVi(dQdx[2], dRdz); } - void +void MT_ExpMap:: compute_dRdVi( - const MT_Quaternion &dQdvi, - MT_Matrix3x3 & dRdvi -) const { - - MT_Scalar prod[9]; + const MT_Quaternion &dQdvi, + MT_Matrix3x3 & dRdvi) const +{ + MT_Scalar prod[9]; /* This efficient formulation is arrived at by writing out the * entire chain rule product dRdq * dqdv in terms of 'q' and * noticing that all the entries are formed from sums of just * nine products of 'q' and 'dqdv' */ - prod[0] = -MT_Scalar(4)*m_q.x()*dQdvi.x(); - prod[1] = -MT_Scalar(4)*m_q.y()*dQdvi.y(); - prod[2] = -MT_Scalar(4)*m_q.z()*dQdvi.z(); - prod[3] = MT_Scalar(2)*(m_q.y()*dQdvi.x() + m_q.x()*dQdvi.y()); - prod[4] = MT_Scalar(2)*(m_q.w()*dQdvi.z() + m_q.z()*dQdvi.w()); - prod[5] = MT_Scalar(2)*(m_q.z()*dQdvi.x() + m_q.x()*dQdvi.z()); - prod[6] = MT_Scalar(2)*(m_q.w()*dQdvi.y() + m_q.y()*dQdvi.w()); - prod[7] = MT_Scalar(2)*(m_q.z()*dQdvi.y() + m_q.y()*dQdvi.z()); - prod[8] = MT_Scalar(2)*(m_q.w()*dQdvi.x() + m_q.x()*dQdvi.w()); + prod[0] = -MT_Scalar(4) * m_q.x() * dQdvi.x(); + prod[1] = -MT_Scalar(4) * m_q.y() * dQdvi.y(); + prod[2] = -MT_Scalar(4) * m_q.z() * dQdvi.z(); + prod[3] = MT_Scalar(2) * (m_q.y() * dQdvi.x() + m_q.x() * dQdvi.y()); + prod[4] = MT_Scalar(2) * (m_q.w() * dQdvi.z() + m_q.z() * dQdvi.w()); + prod[5] = MT_Scalar(2) * (m_q.z() * dQdvi.x() + m_q.x() * dQdvi.z()); + prod[6] = MT_Scalar(2) * (m_q.w() * dQdvi.y() + m_q.y() * dQdvi.w()); + prod[7] = MT_Scalar(2) * (m_q.z() * dQdvi.y() + m_q.y() * dQdvi.z()); + prod[8] = MT_Scalar(2) * (m_q.w() * dQdvi.x() + m_q.x() * dQdvi.w()); /* first row, followed by second and third */ dRdvi[0][0] = prod[1] + prod[2]; @@ -157,61 +155,60 @@ compute_dRdVi( // compute partial derivatives dQ/dVi - void +void MT_ExpMap:: compute_dQdVi( - MT_Quaternion *dQdX -) const { - + MT_Quaternion *dQdX) const +{ /* This is an efficient implementation of the derivatives given * in Appendix A of the paper with common subexpressions factored out */ MT_Scalar sinc, termCoeff; if (m_theta < MT_EXPMAP_MINANGLE) { - sinc = 0.5 - m_theta*m_theta/48.0; - termCoeff = (m_theta*m_theta/40.0 - 1.0)/24.0; + sinc = 0.5 - m_theta * m_theta / 48.0; + termCoeff = (m_theta * m_theta / 40.0 - 1.0) / 24.0; } else { MT_Scalar cosp = m_q.w(); - MT_Scalar ang = 1.0/m_theta; + MT_Scalar ang = 1.0 / m_theta; - sinc = m_sinp*ang; - termCoeff = ang*ang*(0.5*cosp - sinc); + sinc = m_sinp * ang; + termCoeff = ang * ang * (0.5 * cosp - sinc); } for (int i = 0; i < 3; i++) { MT_Quaternion& dQdx = dQdX[i]; - int i2 = (i+1)%3; - int i3 = (i+2)%3; + int i2 = (i + 1) % 3; + int i3 = (i + 2) % 3; - MT_Scalar term = m_v[i]*termCoeff; + MT_Scalar term = m_v[i] * termCoeff; - dQdx[i] = term*m_v[i] + sinc; - dQdx[i2] = term*m_v[i2]; - dQdx[i3] = term*m_v[i3]; - dQdx.w() = -0.5*m_v[i]*sinc; + dQdx[i] = term * m_v[i] + sinc; + dQdx[i2] = term * m_v[i2]; + dQdx[i3] = term * m_v[i3]; + dQdx.w() = -0.5 * m_v[i] * sinc; } } // reParametize away from singularity, updating // m_v and m_theta - void +void MT_ExpMap:: -reParametrize( -){ +reParametrize() +{ if (m_theta > MT_PI) { MT_Scalar scl = m_theta; - if (m_theta > MT_2_PI){ /* first get theta into range 0..2PI */ + if (m_theta > MT_2_PI) { /* first get theta into range 0..2PI */ m_theta = MT_Scalar(fmod(m_theta, MT_2_PI)); - scl = m_theta/scl; + scl = m_theta / scl; m_v *= scl; } - if (m_theta > MT_PI){ + if (m_theta > MT_PI) { scl = m_theta; m_theta = MT_2_PI - m_theta; - scl = MT_Scalar(1.0) - MT_2_PI/scl; + scl = MT_Scalar(1.0) - MT_2_PI / scl; m_v *= scl; } } @@ -219,10 +216,10 @@ reParametrize( // compute cached variables - void +void MT_ExpMap:: -angleUpdated( -){ +angleUpdated() +{ m_theta = m_v.length(); reParametrize(); @@ -233,20 +230,21 @@ angleUpdated( m_sinp = MT_Scalar(0.0); /* Taylor Series for sinc */ - MT_Vector3 temp = m_v * MT_Scalar(MT_Scalar(.5) - m_theta*m_theta/MT_Scalar(48.0)); + MT_Vector3 temp = m_v * MT_Scalar(MT_Scalar(.5) - m_theta * m_theta / MT_Scalar(48.0)); m_q.x() = temp.x(); m_q.y() = temp.y(); m_q.z() = temp.z(); m_q.w() = MT_Scalar(1.0); - } else { - m_sinp = MT_Scalar(sin(.5*m_theta)); + } + else { + m_sinp = MT_Scalar(sin(.5 * m_theta)); /* Taylor Series for sinc */ - MT_Vector3 temp = m_v * (m_sinp/m_theta); + MT_Vector3 temp = m_v * (m_sinp / m_theta); m_q.x() = temp.x(); m_q.y() = temp.y(); m_q.z() = temp.z(); - m_q.w() = MT_Scalar(cos(.5*m_theta)); + m_q.w() = MT_Scalar(cos(0.5 * m_theta)); } } diff --git a/intern/itasc/Armature.cpp b/intern/itasc/Armature.cpp index 1dacb8bc184..78780ed8ba3 100644 --- a/intern/itasc/Armature.cpp +++ b/intern/itasc/Armature.cpp @@ -319,7 +319,7 @@ int Armature::addConstraint(const std::string& segment_name, ConstraintCallback return iConstraint; } } - if (m_finalized) { + if (m_finalized) { if (_freeParam && _param) free(_param); return -1; diff --git a/intern/itasc/kdl/utilities/utility_io.cpp b/intern/itasc/kdl/utilities/utility_io.cpp index 0926f424f71..e16a85167bc 100644 --- a/intern/itasc/kdl/utilities/utility_io.cpp +++ b/intern/itasc/kdl/utilities/utility_io.cpp @@ -106,7 +106,7 @@ int _EatSpace( std::istream& is,int* countp=NULL) { // Eats whites, returns, tabs and the delim character -// Checks wether delim char. is encountered. +// Checks whether delim char. is encountered. void Eat( std::istream& is, int delim ) { int ch; @@ -119,7 +119,7 @@ void Eat( std::istream& is, int delim ) } // Eats whites, returns, tabs and the delim character -// Checks wether delim char. is encountered. +// Checks whether delim char. is encountered. // EatEnd does not eat all space-like char's at the end. void EatEnd( std::istream& is, int delim ) { diff --git a/intern/memutil/MEM_RefCountPtr.h b/intern/memutil/MEM_RefCountPtr.h index ffdf927b551..da10e689fbf 100644 --- a/intern/memutil/MEM_RefCountPtr.h +++ b/intern/memutil/MEM_RefCountPtr.h @@ -130,7 +130,7 @@ protected : /** * Protected constructors - * This class is not for direct instanciation. Sub classes + * This class is not for direct instantiation. Sub classes * should only be allocated on the heap. */ diff --git a/intern/raskter/raskter.c b/intern/raskter/raskter.c index e2d4809a23c..659d01e2d82 100644 --- a/intern/raskter/raskter.c +++ b/intern/raskter/raskter.c @@ -37,6 +37,15 @@ #endif +// this is needed for inlining behavior +#if defined _WIN32 +# define DO_INLINE __inline +#elif defined (__sun) || defined (__sun__) +# define DO_INLINE +#else +# define DO_INLINE static inline +#endif + /* * Sort all the edges of the input polygon by Y, then by X, of the "first" vertex encountered. @@ -814,14 +823,14 @@ int get_range_expanded_pixel_coord(float normalized_value, int max_value) { return (int)((normalized_value * (float)(max_value)) + 0.5f); } -__inline float get_pixel_intensity(float *buf, int buf_x, int buf_y, int pos_x, int pos_y) { +DO_INLINE float get_pixel_intensity(float *buf, int buf_x, int buf_y, int pos_x, int pos_y) { if(pos_x < 0 || pos_x >= buf_x || pos_y < 0 || pos_y >= buf_y) { return 0.0f; } return buf[(pos_y * buf_x) + pos_x]; } -__inline float get_pixel_intensity_bilinear(float *buf, int buf_x, int buf_y, float u, float v) { +DO_INLINE float get_pixel_intensity_bilinear(float *buf, int buf_x, int buf_y, float u, float v) { int a; int b; int a_plus_1; @@ -847,7 +856,7 @@ __inline float get_pixel_intensity_bilinear(float *buf, int buf_x, int buf_y, fl } -__inline void set_pixel_intensity(float *buf, int buf_x, int buf_y, int pos_x, int pos_y, float intensity) { +DO_INLINE void set_pixel_intensity(float *buf, int buf_x, int buf_y, int pos_x, int pos_y, float intensity) { if(pos_x < 0 || pos_x >= buf_x || pos_y < 0 || pos_y >= buf_y) { return; } diff --git a/intern/smoke/intern/WAVELET_NOISE.h b/intern/smoke/intern/WAVELET_NOISE.h index 66dfb95d143..4806c6a9fc1 100644 --- a/intern/smoke/intern/WAVELET_NOISE.h +++ b/intern/smoke/intern/WAVELET_NOISE.h @@ -107,7 +107,7 @@ static void downsampleNeumann(const float *from, float *to, int n, int stride) // if these values are not local incorrect results are generated float downCoeffs[32] = { DOWNCOEFFS }; const float *const aCoCenter= &downCoeffs[16]; - for (int i = 0; i < n / 2; i++) { + for (int i = 0; i < ceil((float)n / 2); i++) { to[i * stride] = 0; for (int k = 2 * i - 16; k < 2 * i + 16; k++) { // handle boundary |