ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ObjHelper.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file ObjHelper.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2017 CERN for the benefit of the Acts project
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 
10 
11 #include <vector>
12 
13 void FW::Obj::writeVTN(std::ofstream& stream, VtnCounter& vtnCounter,
14  double scalor, const Acts::Vector3D& vertex,
15  const std::string& vtntype, bool point) {
16  // in case you make a point
17  unsigned int cp = 0;
18  // the counter
19  if (vtntype == "v") {
20  ++vtnCounter.vcounter;
21  cp = vtnCounter.vcounter;
22  } else if (vtntype == "t") {
23  ++vtnCounter.vtcounter;
24  cp = vtnCounter.vtcounter;
25  } else if (vtntype == "vn") {
26  ++vtnCounter.ncounter;
27  cp = vtnCounter.ncounter;
28  } else
29  return;
30 
31  // write out the vertex, texture vertex, normal
32  stream << vtntype << " " << scalor * vertex.x() << " " << scalor * vertex.y()
33  << " " << scalor * vertex.z() << '\n';
34  // we create a point if needed
35  if (point)
36  stream << "p " << cp;
37 }
38 
39 void FW::Obj::constructVerticalFaces(std::ofstream& stream, unsigned int start,
40  const std::vector<unsigned int>& vsides) {
41  // construct the vertical faces
42  size_t nsides = vsides.size();
43  unsigned int sstart = start;
44  for (auto vside : vsides) {
45  if (vside) {
46  // start streaming the side
47  // all but the last
48  if (start - sstart < nsides - 1) {
49  stream << "f " << start << " " << start + 1 << " ";
50  stream << start + nsides + 1 << " " << start + nsides;
51  } else {
52  stream << "f " << start << " " << sstart << " ";
53  stream << sstart + nsides << " " << start + nsides;
54  }
55  }
56  stream << '\n';
57  // increase
58  ++start;
59  }
60 }
61 
62 void FW::Obj::writePlanarFace(std::ofstream& stream, VtnCounter& vtnCounter,
63  double scalor,
64  const std::vector<Acts::Vector3D>& vertices,
65  double thickness,
66  const std::vector<unsigned int>& vsides) {
67  // minimum 3 vertices needed
68  if (vertices.size() < 3)
69  return;
70  // the first vertex
71  unsigned int fvertex = vtnCounter.vcounter + 1;
72  // lets create the normal vector first
73  Acts::Vector3D sideOne = vertices[1] - vertices[0];
74  Acts::Vector3D sideTwo = vertices[2] - vertices[1];
75  Acts::Vector3D nvector(sideTwo.cross(sideOne).normalized());
76  // thickness or not thickness
77  std::vector<int> sides = {0};
78  if (thickness != 0.)
79  sides = {-1, 1};
80  // now write all the vertices - this works w/wo thickness
81  for (auto side : sides) {
82  // save the current vertex counter
83  unsigned int cvc = vtnCounter.vcounter;
84  // loop over the sides
85  for (auto v : vertices)
86  writeVTN(stream, vtnCounter, scalor,
87  v + (0.5 * side * thickness) * nvector, "v");
88 
89  // now write the face
90  stream << "f ";
91  for (auto n = vertices.size(); 0 < n; --n)
92  stream << ++cvc << " ";
93  stream << '\n';
94  }
95  // now process the vertical sides
96  constructVerticalFaces(stream, fvertex, vsides);
97 }
98 
99 void FW::Obj::writeTube(std::ofstream& stream, VtnCounter& vtnCounter,
100  double scalor, unsigned int nSegments,
101  const Acts::Transform3D& transform, double r, double hZ,
102  double thickness) {
103  // flip along plus/minus and declare the faces
104  std::vector<int> flip = {-1, 1};
105  std::vector<int> vfaces = {1, 2, 4, 3};
106  // the number of phisteps
107  double phistep = 2 * M_PI / nSegments;
108  // make it twice if necessary
109  std::vector<double> roffsets = {0.};
110  if (thickness != 0.)
111  roffsets = {-0.5 * thickness, 0.5 * thickness};
112  // now loop over the thickness and make an outer and inner
113  unsigned int cvc = vtnCounter.vcounter;
114  size_t iside = 0;
115  for (auto t : roffsets) {
116  size_t iphi = 0;
117  // loop over phi steps
118  for (; iphi < nSegments; ++iphi) {
119  // currentPhi
120  double phi = -M_PI + iphi * phistep;
121  for (auto iflip : flip) {
122  // create the vertex
123  Acts::Vector3D point(transform * Acts::Vector3D((r + t) * cos(phi),
124  (r + t) * sin(phi),
125  iflip * hZ));
126  // write the normal vector
127  writeVTN(stream, vtnCounter, scalor, point, "v");
128  }
129  }
130  // now create the faces
131  iphi = 0;
132  // side offset for faces
133  unsigned int soff = 2 * iside * nSegments;
134  for (; iphi < nSegments - 1; ++iphi) {
135  // output to file
136  stream << "f ";
137  for (auto face : vfaces)
138  stream << soff + cvc + (2 * iphi) + face << " ";
139  stream << '\n';
140  }
141  // close the loop
142  stream << "f " << soff + cvc + (2 * iphi) + 1 << " "
143  << soff + cvc + (2 * iphi) + 2 << " " << soff + cvc + 2 << " "
144  << soff + cvc + 1 << '\n';
145  // new line at the end of the line
146  stream << '\n';
147  ++iside;
148  }
149 
150  // construct the sides at the end when all vertices are done
151  // Acts::Vector3D nvectorSide = transform.rotation().col(2);
152  if (thickness != 0.) {
153  // loop over the two sides
154  for (iside = 0; iside < 2; ++iside) {
155  // rest iphi
156  size_t iphi = 0;
157  for (; iphi < nSegments - 1; ++iphi) {
158  stream << "f ";
159  unsigned int base = cvc + (2 * iphi) + 1;
160  stream << iside + base << " ";
161  stream << iside + base + 2 << " ";
162  stream << iside + base + (2 * nSegments) + 2 << " ";
163  stream << iside + base + (2 * nSegments) << '\n';
164  }
165  // close the loop
166  stream << "f ";
167  stream << iside + cvc + (2 * iphi) + 1 << " ";
168  stream << iside + cvc + 1 << " ";
169  stream << iside + cvc + 1 + (2 * nSegments) << " ";
170  stream << iside + cvc + (2 * iphi) + 1 + (2 * nSegments) << '\n';
171  }
172  }
173 }
174 
175 // Bezier interpolation, see documentation
177  const Acts::Vector3D& p1,
178  const Acts::Vector3D& p2,
179  const Acts::Vector3D& p3) {
180  double u = 1. - t;
181  double tt = t * t;
182  double uu = u * u;
183  double uuu = uu * u;
184  double ttt = tt * t;
185 
186  Acts::Vector3D p = uuu * p0; // first term
187  p += 3 * uu * t * p1; // second term
188  p += 3 * u * tt * p2; // third term
189  p += ttt * p3; // fourth term
190  return p;
191 }