58 result = LNormald::zero();
64 size_t num_verts = size();
65 for (
size_t i = 0; i < num_verts; i++) {
67 LVertexd p1 =
get_vertex((i + 1) % num_verts)->get_pos3();
68 result[0] += p0[1] * p1[2] - p0[2] * p1[1];
69 result[1] += p0[2] * p1[0] - p0[0] * p1[2];
70 result[2] += p0[0] * p1[1] - p0[1] * p1[0];
73 if (!result.normalize()) {
78 if (cs == CS_default) {
79 cs = get_default_coordinate_system();
81 if (cs == CS_zup_left || cs == CS_yup_left) {
109 nassertr(!empty(),
false);
113 const_iterator vi = begin();
114 LVecBase3d first_point = (*vi)->get_pos3();
115 LPlaned plane(normal, first_point);
120 while (vi != end()) {
121 LVecBase3d this_point = (*vi)->get_pos3();
122 if (!this_point.almost_equal(first_point)) {
123 double dist = plane.dist_to_plane(this_point);
124 double tol = dist / length(this_point - first_point);
125 if (!IS_THRESHOLD_ZERO(tol, 0.0001)) {
147 triangulate_in_place(
bool convex_also) {
149 nassertr(parent !=
nullptr,
this);
152 parent->remove_child(
this);
153 triangulate_poly(parent, convex_also);
162 write(std::ostream &out,
int indent_level)
const {
164 write_body(out, indent_level+2);
165 indent(out, indent_level) <<
"}\n";
173 decomp_concave(
EggGroupNode *container,
int asum,
int x,
int y)
const {
174 #define VX(p, c) p->coord[c] 179 struct DecompVtx *next;
182 DecompVtx *p0, *p1, *p2, *t0, *vert;
184 double xmin, xmax, ymin, ymax;
185 int i, init, csum, chek;
186 double a[3], b[3], c[3], s[3];
188 int num_verts = size();
189 nassertr(num_verts >= 3,
false);
192 vert = (DecompVtx *) alloca(
sizeof(DecompVtx));
197 for (i = 1; i < num_verts; i++) {
198 p0 = (DecompVtx *) alloca(
sizeof(DecompVtx));
203 if (!(p0->coord == p1->coord)) {
218 while (p0 != p2->next) {
230 a[0] = VX(p1, y) - VX(p2, y);
231 b[0] = VX(p2, x) - VX(p1, x);
232 a[2] = VX(p0, y) - VX(p1, y);
233 b[2] = VX(p1, x) - VX(p0, x);
235 csum = ((b[0] * a[2] - b[2] * a[0] >= 0.0) ? 1 : 0);
245 xmin = (VX(p0, x) < VX(p1, x)) ? VX(p0, x) : VX(p1, x);
246 if (xmin > VX(p2, x))
249 xmax = (VX(p0, x) > VX(p1, x)) ? VX(p0, x) : VX(p1, x);
250 if (xmax < VX(p2, x))
253 ymin = (VX(p0, y) < VX(p1, y)) ? VX(p0, y) : VX(p1, y);
254 if (ymin > VX(p2, y))
257 ymax = (VX(p0, y) > VX(p1, y)) ? VX(p0, y) : VX(p1, y);
258 if (ymax < VX(p2, y))
261 for (init = 1, t0 = p2->next; t0 != p0; t0 = t0->next) {
262 if (VX(t0, x) >= xmin && VX(t0, x) <= xmax &&
263 VX(t0, y) >= ymin && VX(t0, y) <= ymax) {
265 a[1] = VX(p2, y) - VX(p0, y);
266 b[1] = VX(p0, x) - VX(p2, x);
268 c[0] = VX(p1, x) * VX(p2, y) - VX(p2, x) * VX(p1, y);
269 c[1] = VX(p2, x) * VX(p0, y) - VX(p0, x) * VX(p2, y);
270 c[2] = VX(p0, x) * VX(p1, y) - VX(p1, x) * VX(p0, y);
273 s[0] = a[0] * VX(t0, x) + b[0] * VX(t0, y) + c[0];
274 s[1] = a[1] * VX(t0, x) + b[1] * VX(t0, y) + c[1];
275 s[2] = a[2] * VX(t0, x) + b[2] * VX(t0, y) + c[2];
278 if (s[0] >= 0.0 && s[1] >= 0.0 && s[2] >= 0.0)
281 if (s[0] <= 0.0 && s[1] <= 0.0 && s[2] <= 0.0)
300 if (triangle->cleanup()) {
323 if (triangle->cleanup()) {
344 triangulate_poly(
EggGroupNode *container,
bool convex_also) {
346 double dx1, dy1, dx2, dy2, max;
347 int i, flag, asum, csum, index, x, y, v0, v1, v, even;
354 int num_verts = size();
355 if (num_verts == 3) {
360 }
else if (num_verts < 3) {
370 for (i = 0; i < num_verts; i++) {
372 p1 =
get_vertex((i + 1) % num_verts)->get_pos3();
373 as[0] += p0[0] * p1[1] - p0[1] * p1[0];
374 as[1] += p0[0] * p1[2] - p0[2] * p1[0];
375 as[2] += p0[1] * p1[2] - p0[2] * p1[1];
382 for (i = 0; i < 3; i++) {
427 asum = ((dx1 * dy2 - dx2 * dy1 >= 0.0) ? 1 : 0);
429 for (i = 0; i < num_verts - 1; i++) {
431 p1 =
get_vertex((i+3) % num_verts)->get_pos3();
437 csum = ((dx1 * dy2 - dx2 * dy1 >= 0.0) ? 1 : 0);
441 return decomp_concave(container, flag, x, y);
465 for (i = 0; i < num_verts - 2; i++) {
473 if (triangle->cleanup()) {
487 if (triangle->cleanup()) {
void write_header(std::ostream &out, int indent_level, const char *egg_keyword) const
Writes the first line of the egg object, e.g.
virtual bool cleanup() override
Cleans up modeling errors in whatever context this makes sense.
bool is_planar() const
Returns true if all of the polygon's vertices lie within the same plane, false otherwise.
A base class for nodes in the hierarchy that are not leaf nodes.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
get_vertex
Returns a particular index based on its index number.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
std::ostream & indent(std::ostream &out, int indent_level)
A handy function for doing text formatting.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
EggNode * add_child(EggNode *node)
Adds the indicated child to the group and returns it.
bool calculate_normal(LNormald &result, CoordinateSystem cs=CS_default) const
Calculates the true polygon normal–the vector pointing out of the front of the polygon–based on the v...
virtual EggPolygon * make_copy() const override
Makes a copy of this object.
void remove_doubled_verts(bool closed)
Certain kinds of primitives, particularly polygons, don't like to have the same vertex repeated conse...
TypeHandle is the identifier used to differentiate C++ class types.
virtual void write(std::ostream &out, int indent_level) const override
Writes the polygon to the indicated output stream in Egg format.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PT(EggPolygon) EggPolygon
Subdivides the polygon into triangles and adds those triangles to the parent group node in place of t...