Beispiel #1
0
vector<Segment> Shape::getCutlines(const Matrix4d &T, double z,
				   vector<Vector2d> &vertices,
				   double &max_gradient,
				   vector<Triangle> &support_triangles,
				   double supportangle,
				   double thickness) const
{
  Vector2d lineStart;
  Vector2d lineEnd;
  vector<Segment> lines;
  // we know our own tranform:
  Matrix4d transform = T * transform3D.transform ;

  int count = (int)triangles.size();
// #ifdef _OPENMP
// #pragma omp parallel for schedule(dynamic)
// #endif
  for (int i = 0; i < count; i++)
    {
      Segment line(-1,-1);
      int num_cutpoints = triangles[i].CutWithPlane(z, transform, lineStart, lineEnd);
      if (num_cutpoints == 0) {
	if (supportangle >= 0 && thickness > 0) {
	  if (triangles[i].isInZrange(z-thickness, z, transform)) {
	    const double slope = -triangles[i].slopeAngle(transform);
	    if (slope >= supportangle) {
	      support_triangles.push_back(triangles[i].transformed(transform));
	    }
	  }
	}
	continue;
      }
      if (num_cutpoints > 0) {
	int havev = find_vertex(vertices, lineStart);
	if (havev >= 0)
	  line.start = havev;
	else {
	  line.start = vertices.size();
	  vertices.push_back(lineStart);
	}
	if (abs(triangles[i].Normal.z()) > max_gradient)
	  max_gradient = abs(triangles[i].Normal.z());
	if (supportangle >= 0) {
	  const double slope = -triangles[i].slopeAngle(transform);
	  if (slope >= supportangle)
	    support_triangles.push_back(triangles[i].transformed(transform));
	}
      }
      if (num_cutpoints > 1) {
	int havev = find_vertex(vertices, lineEnd);
	if (havev >= 0)
	  line.end = havev;
	else {
	  line.end = vertices.size();
	  vertices.push_back(lineEnd);
	}
      }
      // Check segment normal against triangle normal. Flip segment, as needed.
      if (line.start != -1 && line.end != -1 && line.end != line.start)
	{ // if we found a intersecting triangle
	  Vector3d Norm = triangles[i].transformed(transform).Normal;
	  Vector2d triangleNormal = Vector2d(Norm.x(), Norm.y());
	  Vector2d segment = (lineEnd - lineStart);
	  Vector2d segmentNormal(-segment.y(),segment.x());
	  triangleNormal.normalize();
	  segmentNormal.normalize();
	  if( (triangleNormal-segmentNormal).squared_length() > 0.2){
	    // if normals do not align, flip the segment
	    int iswap=line.start;line.start=line.end;line.end=iswap;
	  }
	  // cerr << "line "<<line.start << "-"<<line.end << endl;
	  lines.push_back(line);
	}
    }
  return lines;
}
void UIGeom::render(RenderDevice* rd, float lineScale) {
    if (! visible) {
        return;
    }

    if (m_twoSidedPolys) {
        rd->setCullFace(RenderDevice::CULL_NONE);
        rd->enableTwoSidedLighting();
    }

    for (int i = 0; i < poly3D.size(); ++i) {
        const ConvexPolygon& poly = poly3D[i];
        rd->beginPrimitive(RenderDevice::TRIANGLE_FAN);
            rd->setNormal(poly.normal());
            for (int v = 0; v < poly.numVertices(); ++v) {
                rd->sendVertex(poly.vertex(v));
            }
        rd->endPrimitive();
    }

    // Per segment normals
    Array<Vector3> normal;
    const Vector3 eye = computeEye(rd);
    for (int i = 0; i < line3D.size(); ++i) {
        const PolyLine& line = line3D[i];

        // Compute one normal for each segement
        normal.resize(line.numSegments(), false);
        for (int s = 0; s < line.numSegments(); ++s) {
            normal[s] = segmentNormal(line.segment(s), eye);
        }

        bool closed = line.closed();

        // Compute line width
        {
            Vector4 v = rd->project(line.vertex(0));
            float L = 2;
            if (v.w > 0) {
                L = min(15.0f * v.w, 10.0f);
            } else {
                 L = 10.0f;
            }
            rd->setLineWidth(L * lineScale);
        }

        bool colorWrite = rd->colorWrite();
        bool depthWrite = rd->depthWrite();

        // Draw lines twice.  The first time we draw color information
        // but do not set the depth buffer.  The second time we write
        // to the depth buffer; this prevents line strips from
        // corrupting their own antialiasing with depth conflicts at
        // the line joint points.
        if (colorWrite) {
            rd->setDepthWrite(false);
            rd->beginPrimitive(RenderDevice::LINE_STRIP);
                for (int v = 0; v < line.numVertices(); ++v) {
                    // Compute the smooth normal.  If we have a non-closed
                    // polyline, the ends are special cases.
                    Vector3 N;
                    if (! closed && (v == 0)) {
                        N = normal[0];
                    } else if (! closed && (v == line.numVertices())) {
                        N = normal.last();
                    } else {
                        // Average two adjacent normals
                        N = normal[v % normal.size()] + normal[(v - 1) % 
                                                               normal.size()];
                    }

                    if (N.squaredLength() < 0.05) {
                        // Too small to normalize; revert to the
                        // nearest segment normal
                        rd->setNormal(normal[iMin(v, normal.size() - 1)]);
                    } else {
                        rd->setNormal(N.direction());
                    }

                    rd->sendVertex(line.vertex(v));
                }                
            rd->endPrimitive();
        }

        if (depthWrite) {
            rd->setColorWrite(false);
            rd->setDepthWrite(true);
            rd->beginPrimitive(RenderDevice::LINE_STRIP);
                for (int v = 0; v < line.numVertices(); ++v) {
                    rd->sendVertex(line.vertex(v));
                }
            rd->endPrimitive();
        }

        rd->setColorWrite(colorWrite);
        rd->setDepthWrite(depthWrite);
    }
}