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)) {
147triangulate_in_place(
bool convex_also) {
149 nassertr(parent !=
nullptr,
this);
152 parent->remove_child(
this);
153 triangulate_poly(parent, convex_also);
162write(std::ostream &out,
int indent_level)
const {
164 write_body(out, indent_level+2);
165 indent(out, indent_level) <<
"}\n";
173decomp_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()) {
344triangulate_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()) {
A base class for nodes in the hierarchy that are not leaf nodes.
EggNode * add_child(EggNode *node)
Adds the indicated child to the group and returns it.
void write_header(std::ostream &out, int indent_level, const char *egg_keyword) const
Writes the first line of the egg object, e.g.
bool is_planar() const
Returns true if all of the polygon's vertices lie within the same plane, false otherwise.
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 void write(std::ostream &out, int indent_level) const override
Writes the polygon to the indicated output stream in Egg format.
virtual EggPolygon * make_copy() const override
Makes a copy of this object.
virtual bool cleanup() override
Cleans up modeling errors in whatever context this makes sense.
get_vertex
Returns a particular index based on its index number.
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.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
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.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.