15 #include "eggPolygon.h" 16 #include "eggGroupNode.h" 65 size_t num_verts = size();
66 for (
size_t i = 0; i < num_verts; i++) {
69 result[0] += p0[1] * p1[2] - p0[2] * p1[1];
70 result[1] += p0[2] * p1[0] - p0[0] * p1[2];
71 result[2] += p0[0] * p1[1] - p0[1] * p1[0];
79 if (cs == CS_default) {
80 cs = get_default_coordinate_system();
82 if (cs == CS_zup_left || cs == CS_yup_left) {
113 nassertr(!empty(),
false);
117 const_iterator vi = begin();
119 LPlaned plane(normal, first_point);
124 while (vi != end()) {
127 double dist = plane.dist_to_plane(this_point);
128 double tol = dist / length(this_point - first_point);
129 if (!IS_THRESHOLD_ZERO(tol, 0.0001)) {
156 triangulate_in_place(
bool convex_also) {
161 parent->remove_child(
this);
162 triangulate_poly(parent, convex_also);
174 write(ostream &out,
int indent_level)
const {
176 write_body(out, indent_level+2);
177 indent(out, indent_level) <<
"}\n";
188 decomp_concave(
EggGroupNode *container,
int asum,
int x,
int y)
const {
189 #define VX(p, c) p->coord[c] 194 struct DecompVtx *next;
197 DecompVtx *p0, *p1, *p2, *t0, *vert;
199 double xmin, xmax, ymin, ymax;
200 int i, init, csum, chek;
201 double a[3], b[3], c[3], s[3];
203 int num_verts = size();
204 nassertr(num_verts >= 3,
false);
207 vert = (DecompVtx *) alloca(
sizeof(DecompVtx));
212 for (i = 1; i < num_verts; i++) {
213 p0 = (DecompVtx *) alloca(
sizeof(DecompVtx));
218 if (!(p0->coord == p1->coord)) {
233 while (p0 != p2->next) {
245 a[0] = VX(p1, y) - VX(p2, y);
246 b[0] = VX(p2, x) - VX(p1, x);
247 a[2] = VX(p0, y) - VX(p1, y);
248 b[2] = VX(p1, x) - VX(p0, x);
250 csum = ((b[0] * a[2] - b[2] * a[0] >= 0.0) ? 1 : 0);
260 xmin = (VX(p0, x) < VX(p1, x)) ? VX(p0, x) : VX(p1, x);
261 if (xmin > VX(p2, x))
264 xmax = (VX(p0, x) > VX(p1, x)) ? VX(p0, x) : VX(p1, x);
265 if (xmax < VX(p2, x))
268 ymin = (VX(p0, y) < VX(p1, y)) ? VX(p0, y) : VX(p1, y);
269 if (ymin > VX(p2, y))
272 ymax = (VX(p0, y) > VX(p1, y)) ? VX(p0, y) : VX(p1, y);
273 if (ymax < VX(p2, y))
276 for (init = 1, t0 = p2->next; t0 != p0; t0 = t0->next) {
277 if (VX(t0, x) >= xmin && VX(t0, x) <= xmax &&
278 VX(t0, y) >= ymin && VX(t0, y) <= ymax) {
280 a[1] = VX(p2, y) - VX(p0, y);
281 b[1] = VX(p0, x) - VX(p2, x);
283 c[0] = VX(p1, x) * VX(p2, y) - VX(p2, x) * VX(p1, y);
284 c[1] = VX(p2, x) * VX(p0, y) - VX(p0, x) * VX(p2, y);
285 c[2] = VX(p0, x) * VX(p1, y) - VX(p1, x) * VX(p0, y);
288 s[0] = a[0] * VX(t0, x) + b[0] * VX(t0, y) + c[0];
289 s[1] = a[1] * VX(t0, x) + b[1] * VX(t0, y) + c[1];
290 s[2] = a[2] * VX(t0, x) + b[2] * VX(t0, y) + c[2];
293 if (s[0] >= 0.0 && s[1] >= 0.0 && s[2] >= 0.0)
296 if (s[0] <= 0.0 && s[1] <= 0.0 && s[2] <= 0.0)
315 if (triangle->cleanup()) {
338 if (triangle->cleanup()) {
366 triangulate_poly(
EggGroupNode *container,
bool convex_also) {
368 double dx1, dy1, dx2, dy2, max;
369 int i, flag, asum, csum, index, x, y, v0, v1, v, even;
376 int num_verts = size();
377 if (num_verts == 3) {
382 }
else if (num_verts < 3) {
392 for (i = 0; i < num_verts; i++) {
395 as[0] += p0[0] * p1[1] - p0[1] * p1[0];
396 as[1] += p0[0] * p1[2] - p0[2] * p1[0];
397 as[2] += p0[1] * p1[2] - p0[2] * p1[1];
404 for (i = 0; i < 3; i++) {
449 asum = ((dx1 * dy2 - dx2 * dy1 >= 0.0) ? 1 : 0);
451 for (i = 0; i < num_verts - 1; i++) {
459 csum = ((dx1 * dy2 - dx2 * dy1 >= 0.0) ? 1 : 0);
463 return decomp_concave(container, flag, x, y);
487 for (i = 0; i < num_verts - 2; i++) {
495 if (triangle->cleanup()) {
509 if (triangle->cleanup()) {
virtual void write(ostream &out, int indent_level) const
Writes the polygon to the indicated output stream in Egg format.
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.
LVertexd get_pos3() const
Valid if get_num_dimensions() returns 3 or 4.
static const LVector3d & zero()
Returns a zero-length vector.
virtual bool cleanup()
Cleans up modeling errors in whatever context this makes sense.
bool normalize()
Normalizes the vector in place.
bool almost_equal(const LVecBase3d &other, double threshold) const
Returns true if two vectors are memberwise equal within a specified tolerance.
void write_header(ostream &out, int indent_level, const char *egg_keyword) const
Writes the first line of the egg object, e.g.
This is the base class for all three-component vectors and points.
This is a three-component vector distance (as opposed to a three-component point, which represents a ...
This is a three-component point in space (as opposed to a three-component vector, which represents a ...
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...
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.
EggVertex * get_vertex(int index) const
Returns a particular index based on its index number.