TexGen
Domain.cpp
Go to the documentation of this file.
1/*=============================================================================
2TexGen: Geometric textile modeller.
3Copyright (C) 2006 Martin Sherburn
4
5This program is free software; you can redistribute it and/or
6modify it under the terms of the GNU General Public License
7as published by the Free Software Foundation; either version 2
8of the License, or (at your option) any later version.
9
10This program is distributed in the hope that it will be useful,
11but WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18=============================================================================*/
19
20#include "PrecompiledHeaders.h"
21#include "Domain.h"
22#include "TexGen.h"
23#include "Yarn.h"
24
25using namespace TexGen;
26CDomain::CDomain(void)
27{
28}
29
31{
32}
33
34CDomain::CDomain(TiXmlElement &Element)
35{
36 TiXmlElement* pMesh = Element.FirstChildElement("Mesh");
37 if (pMesh)
38 {
39 m_Mesh = CMesh(*pMesh);
40 }
41}
42
43void CDomain::PopulateTiXmlElement(TiXmlElement &Element, OUTPUT_TYPE OutputType) const
44{
45 Element.SetAttribute("type", GetType());
46 if (OutputType == OUTPUT_FULL)
47 {
48 TiXmlElement Mesh("Mesh");
49 m_Mesh.PopulateTiXmlElement(Mesh, OutputType);
50 Element.InsertEndChild(Mesh);
51 }
52}
53
55{
56 return dynamic_cast<CDomainPrism*>(this);
57}
58
59vector<pair<int, int> > CDomain::ConvertLimitsToInt(const vector<pair<double, double> > &RepeatLimits)
60{
61 vector<pair<int, int> > IntRepeatLimits;
62 vector<pair<double, double> >::const_iterator itRepeatLimits;
63 for (itRepeatLimits = RepeatLimits.begin(); itRepeatLimits != RepeatLimits.end(); ++itRepeatLimits)
64 {
65 IntRepeatLimits.push_back(pair<int, int>((int)ceil(itRepeatLimits->first), (int)floor(itRepeatLimits->second)));
66 }
67 return IntRepeatLimits;
68}
69
70double CDomain::GetVolume() const
71{
72 return m_Mesh.CalculateVolume();
73}
74
75bool CDomain::MeshIntersectsDomain(const CMesh &Mesh) const
76{
77 pair<XYZ, XYZ> DomainAABB = m_Mesh.GetAABB();
78 pair<XYZ, XYZ> MeshAABB = Mesh.GetAABB();
79
80 return BoundingBoxIntersect(DomainAABB.first, DomainAABB.second, MeshAABB.first, MeshAABB.second);
81}
82
83vector<XYZ> CDomain::GetTranslations(const CYarn &Yarn) const
84{
85 vector<XYZ> AllRepeats;
86 vector<XYZ> FiniteRepeats;
87 const vector<XYZ> &YarnRepeats = Yarn.GetRepeats();
88 vector<pair<int, int> > RepeatLimits = GetRepeatLimits(Yarn); // How many times to repeat from original yarn
89 vector<XYZ>::const_iterator itRepeat;
90 vector<pair<int, int> >::const_iterator itLimits;
91 AllRepeats.push_back(XYZ());
92 for (itRepeat = YarnRepeats.begin(), itLimits = RepeatLimits.begin(); itRepeat != YarnRepeats.end() && itLimits != RepeatLimits.end(); ++itRepeat, ++itLimits)
93 {
94 CopyToRange(AllRepeats, *itRepeat, itLimits->first, itLimits->second);
95 }
96 CMesh Mesh; // Create an empty mesh
97 Yarn.AddAABBToMesh(Mesh); // Adds bounding box of yarn surfaces to mesh (?)
98 for (itRepeat = AllRepeats.begin(); itRepeat != AllRepeats.end(); ++itRepeat)
99 {
100 CMesh RepeatedMesh = Mesh;
101 RepeatedMesh.Translate(*itRepeat);
102 if (MeshIntersectsDomain(RepeatedMesh))
103 FiniteRepeats.push_back(*itRepeat);
104 }
105 return FiniteRepeats;
106}
107
108pair<double, double> CDomain::GetLimits(XYZ RepeatVector, const CMesh &Mesh) const
109{
110 pair<double, double> DomainLimits = make_pair(0.0, 0.0);
111 pair<double, double> MeshLimits = make_pair(0.0, 0.0);
112 pair<double, double> Limits = make_pair(0.0, 0.0);
113 double dPointDist;//, dFurthestPointDist = 0;
114 vector<XYZ>::const_iterator itNode;
115 const vector<XYZ> MeshNodes = m_Mesh.GetNodes();
116
117 double dRepeatLength = GetLength(RepeatVector);
118 RepeatVector /= dRepeatLength;
119 //for (itNode = m_Mesh.NodesBegin(); itNode != m_Mesh.NodesEnd(); ++itNode)
120 for (itNode = MeshNodes.begin(); itNode != MeshNodes.end(); ++itNode)
121 {
122 dPointDist = DotProduct(*itNode, RepeatVector);
123
124 if (itNode == MeshNodes.begin())
125 DomainLimits = make_pair(dPointDist, dPointDist);
126 else if (DomainLimits.first > dPointDist)
127 DomainLimits.first = dPointDist;
128 else if (DomainLimits.second < dPointDist)
129 DomainLimits.second = dPointDist;
130 }
131
132 for (itNode = Mesh.NodesBegin(); itNode != Mesh.NodesEnd(); ++itNode)
133 {
134 dPointDist = DotProduct(*itNode, RepeatVector);
135
136 if (itNode == Mesh.NodesBegin())
137 MeshLimits = make_pair(dPointDist, dPointDist);
138 else if (MeshLimits.first > dPointDist)
139 MeshLimits.first = dPointDist;
140 else if (MeshLimits.second < dPointDist)
141 MeshLimits.second = dPointDist;
142 }
143 Limits.first = (DomainLimits.first - MeshLimits.second) / dRepeatLength;
144 Limits.second = (DomainLimits.second - MeshLimits.first) / dRepeatLength;
145 return Limits;
146}
147
148vector<pair<int, int> > CDomain::GetRepeatLimits(const CYarn &Yarn) const
149{
150 //TGLOGINDENT("Getting yarn repeat limits");
151
152 vector<pair<double, double> > AllRepeatLimitsPrevious;
153 vector<pair<double, double> > AllRepeatLimits;
154 AllRepeatLimits.resize(Yarn.GetRepeats().size(), pair<double, double>(0, 0));
155 vector<XYZ>::const_iterator itRepeat;
156 vector<PLANE>::const_iterator itPlane;
157 int i;
158 int iIterations = 0, iMaxIterations = 100;
159
160 // Check for all repeats being set to zero
161 int j = 0;
162 for (itRepeat = Yarn.GetRepeats().begin(); itRepeat != Yarn.GetRepeats().end(); ++itRepeat)
163 {
164 if (!(*itRepeat))
165 ++j;
166 }
167 if (j == Yarn.GetRepeats().size())
168 return vector<pair<int, int> >();
169
170 // Use an iterative method to find the repeat limits
171 do
172 {
173 ++iIterations;
174 AllRepeatLimitsPrevious = AllRepeatLimits;
175 // Loop over all the repeats
176 for (itRepeat = Yarn.GetRepeats().begin(), i = 0; itRepeat != Yarn.GetRepeats().end(); ++itRepeat, ++i)
177 {
178 AllRepeatLimits[i] = pair<double, double>(0, 0);
179 CMesh Mesh; // Create an empty mesh
180 // Get a surface mesh of the yarns with the repeats calculated so far
181 if (!Yarn.AddAABBToMesh(Mesh, ConvertLimitsToInt(AllRepeatLimits)))
182 {
183 TGERROR("Unable to calculate repeat limits");
184 assert(false);
185 return ConvertLimitsToInt(AllRepeatLimits);
186 }
187
188 AllRepeatLimits[i] = GetLimits(*itRepeat, Mesh);
189 }
190 // Keep going until the repeats from the previous iteration are the same as the repeats for the current
191 // iteration. Or until the operation fails due to too many iterations.
192 } while (AllRepeatLimitsPrevious != AllRepeatLimits && iIterations < iMaxIterations);
193 if (iIterations >= iMaxIterations)
194 {
195 TGERROR("Unable to find yarn repeat limits, stopped after " << iIterations << " iterations");
196 return vector<pair<int, int> >();
197 }
198 //TGLOG("Found yarn repeat limits after " << iIterations << " iterations");
199 return ConvertLimitsToInt(AllRepeatLimits);
200}
201
#define TGERROR(MESSAGE)
Macros used to report the file name and line number to the TexGenError and TexGenLog functions.
Definition: Logger.h:29
CDomainPrism * GetPrismDomain()
Definition: Domain.cpp:54
CDomain(void)
Definition: Domain.cpp:26
pair< double, double > GetLimits(XYZ RepeatVector, const CMesh &Mesh) const
Get the limits for a single given repeat vector and surface mesh.
Definition: Domain.cpp:108
virtual string GetType() const =0
Derived class should return the class name.
virtual double GetVolume() const
Get the volume of the domain.
Definition: Domain.cpp:70
virtual void PopulateTiXmlElement(TiXmlElement &Element, OUTPUT_TYPE OutputType=OUTPUT_STANDARD) const
Used for saving data to XML.
Definition: Domain.cpp:43
bool MeshIntersectsDomain(const CMesh &Mesh) const
Determine if a mesh intersects with the domain.
Definition: Domain.cpp:75
virtual ~CDomain(void)
Definition: Domain.cpp:30
CMesh m_Mesh
A mesh representing the domain as a surface mesh.
Definition: Domain.h:112
vector< XYZ > GetTranslations(const CYarn &Yarn) const
Get the translation vectors necessary to fully fill the domain.
Definition: Domain.cpp:83
vector< pair< int, int > > GetRepeatLimits(const CYarn &Yarn) const
Definition: Domain.cpp:148
static vector< pair< int, int > > ConvertLimitsToInt(const vector< pair< double, double > > &RepeatLimits)
Definition: Domain.cpp:59
Domain implementation described using extrusion of a polygon outline.
Definition: DomainPrism.h:36
Defines the nodes and elements of a surface or volume mesh.
Definition: Mesh.h:58
const vector< XYZ > & GetNodes() const
Get a const reference to the nodes.
Definition: Mesh.cpp:2656
void PopulateTiXmlElement(TiXmlElement &Element, OUTPUT_TYPE OutputType) const
Used for saving data to XML.
Definition: Mesh.cpp:57
void Translate(XYZ Vector)
Translate whole mesh by given vector.
Definition: Mesh.cpp:1139
double CalculateVolume() const
Calculate the volume of the mesh.
Definition: Mesh.cpp:1519
pair< XYZ, XYZ > GetAABB(double dGrowDistance=0) const
Get an axis aligned bounding box for the mesh.
Definition: Mesh.cpp:340
vector< XYZ >::const_iterator NodesBegin() const
Definition: Mesh.cpp:2604
vector< XYZ >::const_iterator NodesEnd() const
Definition: Mesh.cpp:2609
Represents a yarn consisting of master nodes, section and interpolation function.
Definition: Yarn.h:49
const vector< XYZ > & GetRepeats() const
Definition: Yarn.h:448
bool AddAABBToMesh(CMesh &Mesh) const
Add the axis aligned bounding box of the yarn to the Mesh.
Definition: Yarn.cpp:702
Namespace containing a series of customised math operations not found in the standard c++ library.
void CopyToRange(vector< XYZ > &Offsets, XYZ Vector, int iLowerLimit, int iUpperLimit)
Definition: Misc.cpp:47
OUTPUT_TYPE
Definition: Misc.h:105
@ OUTPUT_FULL
Definition: Misc.h:108
double GetLength(const XYZ &Point1, const XYZ &Point2)
Get the length between two points.
Definition: mymath.h:540
bool BoundingBoxIntersect(const XYZ &BBox1Min, const XYZ &BBox1Max, const XYZ &BBox2Min, const XYZ &BBox2Max, double dTolerance=0)
Find if two AABBs intersect with given tolerance.
Definition: mymath.h:970
double DotProduct(const XYZ &left, const XYZ &right)
Get the dot product of two vectors.
Definition: mymath.h:512
Struct for representing points in 3D space.
Definition: mymath.h:56