예제 #1
0
WVertex *Winged::createVertex(const Vector3 &p) {
  WVertex *res;
  res=new WVertex(p,this);
  _vertex.push_back(res);
  res->index(_vertex.size()-1);
  return res;
}
예제 #2
0
파일: WFace.cpp 프로젝트: malikboukrou/m3ds
void WFace::draw(bool withNormal) {
    WEdge *e, *e_new, *start;
    WVertex *v;
    e=start=this->edge();

    vector<Vector3> position;
    position.clear();

    vector<Vector3> normal;
    normal.clear();

    do {
          if(e->left()==this){
            e_new = e->succLeft();
            v = e->begin();
          }
          else{
            e_new = e->succRight();
            v = e->end();
          }
           position.push_back(v->position());
           normal.push_back(v->normal());
          e = e_new;
      } while(e != start);


    // A Laisser à la fin (effectue un affichage polygone par polygone : lent => uniquement pour vérification/TP)
    if (withNormal)
        p3d::drawPolygon(position,normal,true);
    else
        p3d::drawPolygon(position,false,0.8);

}
void WingedEdgeBuilder::buildWVertices(WShape& shape, const real *vertices, unsigned vsize)
{
	WVertex *vertex;
	for (unsigned int i = 0; i < vsize; i += 3) {
		vertex = new WVertex(Vec3r(vertices[i], vertices[i + 1], vertices[i + 2]));
		vertex->setId(i / 3);
		shape.AddVertex(vertex);
	}
}
예제 #4
0
/** ************************************************************************************
** A COMPLETER : WFace::computePointFace() => point de face de catmull clark (iso barycentre des sommets).
** rappel : les coordonnés d'un sommet WVertex *v s'obtiennent par v->point() (de type Vector3).
** ************************************************************************************ */
void WFace::computePointFace() {
  WEdge *e=edge();
  Vector3 barycentre;
  WVertex *v;
  int nbedge=0;
  barycentre.set(0,0,0);
  do {
    if (e->left()==this) v=e->begin(); else v=e->end();
    barycentre+=v->position();
    nbedge++;
    if (e->left()==this) e=e->succLeft(); else e=e->succRight();
  } while (e!=edge());
  barycentre=barycentre/nbedge;

  // affectation point de face
  _pointFace=barycentre;
}
예제 #5
0
// TODO: check optimizations:
// use marking ? (measure *timings* ...)
void compute_curvature_tensor(WVertex *start, real radius, NormalCycle& nc)
{
	// in case we have a non-manifold vertex, skip it...
	if (start->isBoundary())
		return;

	std::set<WVertex*> vertices;
	const Vec3r& O = start->GetVertex();
	std::stack<WVertex*> S;
	S.push(start);
	vertices.insert(start);
	while (!S.empty()) {
		WVertex *v = S.top();
		S.pop();
		if (v->isBoundary())
			continue;
		const Vec3r& P = v->GetVertex();
		WVertex::incoming_edge_iterator woeit = v->incoming_edges_begin();
		WVertex::incoming_edge_iterator woeitend = v->incoming_edges_end();
		for (; woeit != woeitend; ++woeit) {
			WOEdge *h = *woeit;
			if ((v == start) || h->GetVec() * (O - P) > 0.0) {
				Vec3r V(-1 * h->GetVec());
				bool isect = sphere_clip_vector(O, radius, P, V);
				assert (h->GetOwner()->GetNumberOfOEdges() == 2); // Because otherwise v->isBoundary() would be true
				nc.accumulate_dihedral_angle(V, h->GetAngle());

				if (!isect) {
					WVertex *w = h->GetaVertex();
					if (vertices.find(w) == vertices.end()) {
						vertices.insert(w);
						S.push(w);
					}
				}
			}
		}
	}
}
예제 #6
0
WShape::WShape(WShape& iBrother)
{
	_Id = iBrother.GetId();
	_Name = iBrother._Name;
	_FrsMaterials = iBrother._FrsMaterials;
	_meanEdgeSize = iBrother._meanEdgeSize;
	iBrother.bbox(_min, _max);
	vector<WVertex *>& vertexList = iBrother.getVertexList();
	vector<WVertex *>::iterator v = vertexList.begin(), vend = vertexList.end();
	for (; v != vend; ++v) {
		//WVertex *newVertex = new WVertex(*(*v));
		WVertex *newVertex = (*v)->duplicate();

		newVertex->setShape(this);
		AddVertex(newVertex);
	}

	vector<WEdge *>& edgeList = iBrother.getEdgeList();
	vector<WEdge *>::iterator e = edgeList.begin(), eend = edgeList.end();
	for (; e != eend; ++e) {
		//WEdge *newEdge = new WEdge(*(*e));
		WEdge *newEdge = (*e)->duplicate();
		AddEdge(newEdge);
	}

	vector<WFace *>& faceList = iBrother.GetFaceList();
	vector<WFace *>::iterator f = faceList.begin(), fend = faceList.end();
	for (; f != fend; ++f) {
		//WFace *newFace = new WFace(*(*f));
		WFace *newFace = (*f)->duplicate();
		AddFace(newFace);
	}

	// update all pointed addresses thanks to the newly created objects:
	vend = _VertexList.end();
	for (v = _VertexList.begin(); v != vend; ++v) {
		const vector<WEdge *>& vedgeList = (*v)->GetEdges();
		vector<WEdge *> newvedgelist;
		unsigned int i;
		for (i = 0; i < vedgeList.size(); i++) {
			WEdge *current = vedgeList[i];
			edgedata *currentvedata = (edgedata *)current->userdata;
			newvedgelist.push_back(currentvedata->_copy);
		}
		(*v)->setEdges(newvedgelist);
	}

	eend = _EdgeList.end();
	for (e = _EdgeList.begin(); e != eend; ++e) {
		// update aOedge:
		WOEdge *aoEdge = (*e)->GetaOEdge();
		aoEdge->setaVertex(((vertexdata *)(aoEdge->GetaVertex()->userdata))->_copy);
		aoEdge->setbVertex(((vertexdata *)(aoEdge->GetbVertex()->userdata))->_copy);
		if (aoEdge->GetaFace())
			aoEdge->setaFace(((facedata *)(aoEdge->GetaFace()->userdata))->_copy);
		aoEdge->setbFace(((facedata *)(aoEdge->GetbFace()->userdata))->_copy);
		aoEdge->setOwner(((edgedata *)(aoEdge->GetOwner()->userdata))->_copy);

		// update bOedge:
		WOEdge *boEdge = (*e)->GetbOEdge();
		if (boEdge) {
			boEdge->setaVertex(((vertexdata *)(boEdge->GetaVertex()->userdata))->_copy);
			boEdge->setbVertex(((vertexdata *)(boEdge->GetbVertex()->userdata))->_copy);
			if (boEdge->GetaFace())
				boEdge->setaFace(((facedata *)(boEdge->GetaFace()->userdata))->_copy);
			boEdge->setbFace(((facedata *)(boEdge->GetbFace()->userdata))->_copy);
			boEdge->setOwner(((edgedata *)(boEdge->GetOwner()->userdata))->_copy);
		}
	}

	fend = _FaceList.end();
	for (f = _FaceList.begin(); f != fend; ++f) {
		unsigned int i;
		const vector<WOEdge *>& oedgeList = (*f)->getEdgeList();
		vector<WOEdge *> newoedgelist;

		unsigned int n = oedgeList.size();
		for (i = 0; i < n; i++) {
			WOEdge *current = oedgeList[i];
			oedgedata *currentoedata = (oedgedata *)current->userdata;
			newoedgelist.push_back(currentoedata->_copy);
			//oedgeList[i] = currentoedata->_copy;
			//oedgeList[i] = ((oedgedata *)(oedgeList[i]->userdata))->_copy;
		}
		(*f)->setEdgeList(newoedgelist);
	}

	// Free all memory (arghh!)
	// Vertex
	vend = iBrother.getVertexList().end();
	for (v = iBrother.getVertexList().begin(); v != vend; ++v) {
		delete (vertexdata *)((*v)->userdata);
		(*v)->userdata = NULL;
	}

	// Edges and OEdges:
	eend = iBrother.getEdgeList().end();
	for (e = iBrother.getEdgeList().begin(); e != eend; ++e) {
		delete (edgedata *)((*e)->userdata);
		(*e)->userdata = NULL;
		// OEdge a:
		delete (oedgedata *)((*e)->GetaOEdge()->userdata);
		(*e)->GetaOEdge()->userdata = NULL;
		// OEdge b:
		WOEdge *oedgeb = (*e)->GetbOEdge();
		if (oedgeb) {
			delete (oedgedata *)(oedgeb->userdata);
			oedgeb->userdata = NULL;
		}
	}

	// Faces
	fend = iBrother.GetFaceList().end();
	for (f = iBrother.GetFaceList().begin(); f != fend; ++f) {
		delete (facedata *)((*f)->userdata);
		(*f)->userdata = NULL;
	}
}
예제 #7
0
void FEdgeXDetector::ProcessRidgeFace(WXFace *iFace)
{
	// RIDGE LAYER
	// Compute the RidgeFunction, that is the derivative of the ppal curvature along e1 at each vertex of the face
	WVertex *v;
	Vec3r v1v2;
	real t;
	vector<WXFaceLayer*> SmoothLayers;
	WXFaceLayer *faceLayer;
	Face_Curvature_Info *layer_info;
	real K1_a(0), K1_b(0);
	Vec3r Inter_a, Inter_b;

	// find the ridge layer of the face
	iFace->retrieveSmoothLayers(Nature::RIDGE, SmoothLayers);
	if ( SmoothLayers.size()!=1 )
		return;
	faceLayer = SmoothLayers[0];
	// retrieve the curvature info of this layer
	layer_info = (Face_Curvature_Info *)faceLayer->userdata;

	int numVertices = iFace->numberOfVertices();
	for (int i = 0; i < numVertices; i++) {
		v = iFace->GetVertex(i);
		// vec_curvature_info[i] contains the curvature info of this vertex
		Vec3r e2 = layer_info->vec_curvature_info[i]->K2*layer_info->vec_curvature_info[i]->e2;
		Vec3r e1 = layer_info->vec_curvature_info[i]->K1*layer_info->vec_curvature_info[i]->e1;
		e2.normalize();

		WVertex::face_iterator fit = v->faces_begin();
		WVertex::face_iterator fitend = v->faces_end();
		for (; fit != fitend; ++fit) {
			WXFace *wxf = dynamic_cast<WXFace*>(*fit);
			WOEdge *oppositeEdge;
			if (!(wxf->getOppositeEdge(v, oppositeEdge)))
				continue;
			v1v2 = oppositeEdge->GetbVertex()->GetVertex() - oppositeEdge->GetaVertex()->GetVertex();
			GeomUtils::intersection_test res;
			res = GeomUtils::intersectRayPlane(oppositeEdge->GetaVertex()->GetVertex(), v1v2, e2, -(v->GetVertex()*e2),
			                                   t, 1.0e-06);
			if ((res == GeomUtils::DO_INTERSECT) && (t >= 0.0) && (t <= 1.0)) {
				vector<WXFaceLayer*> second_ridge_layer;
				wxf->retrieveSmoothLayers(Nature::RIDGE, second_ridge_layer);
				if (second_ridge_layer.size() != 1)
					continue;
				Face_Curvature_Info *second_layer_info = (Face_Curvature_Info*)second_ridge_layer[0]->userdata;

				unsigned index1 = wxf->GetIndex(oppositeEdge->GetaVertex());
				unsigned index2 = wxf->GetIndex(oppositeEdge->GetbVertex());
				real K1_1 = second_layer_info->vec_curvature_info[index1]->K1;
				real K1_2 = second_layer_info->vec_curvature_info[index2]->K1;
				real K1 = (1.0 - t) * K1_1 + t * K1_2;
				Vec3r inter((1.0 - t) * oppositeEdge->GetaVertex()->GetVertex() +
				            t * oppositeEdge->GetbVertex()->GetVertex());
				Vec3r vtmp(inter - v->GetVertex());
				// is it K1_a or K1_b ?
				if (vtmp * e1 > 0) {
					K1_b = K1;
					Inter_b = inter;
				}
				else {
					K1_a = K1;
					Inter_a = inter;
				}
			}
		}
		// Once we have K1 along the ppal direction compute the derivative : K1b - K1a put it in DotP
		//real d = fabs(K1_b) - fabs(K1_a);
		real d = 0;
		real threshold = _meanK1 + (_maxK1 - _meanK1) / 7.0;
		//real threshold = _meanK1;
		//if ((fabs(K1_b) > threshold) || ((fabs(K1_a) > threshold)))
		d = (K1_b) - (K1_a) / (Inter_b - Inter_a).norm();
		faceLayer->PushDotP(d);
		//faceLayer->PushDotP(layer_info->vec_curvature_info[i]->K1);
	}

	// Make the values relevant by checking whether all principal directions have the "same" direction:
	Vec3r e0((layer_info->vec_curvature_info[0]->K1 * layer_info->vec_curvature_info[0]->e1));
	e0.normalize();
	Vec3r e1((layer_info->vec_curvature_info[1]->K1 * layer_info->vec_curvature_info[1]->e1));
	e1.normalize();
	Vec3r e2((layer_info->vec_curvature_info[2]->K1 * layer_info->vec_curvature_info[2]->e1));
	e2.normalize();
	if (e0 * e1 < 0)
		// invert dotP[1]
		faceLayer->ReplaceDotP(1, -faceLayer->dotP(1));
	if (e0 * e2 < 0)
		// invert dotP[2]
		faceLayer->ReplaceDotP(2, -faceLayer->dotP(2));

#if 0 // remove the weakest values;
	real minDiff = (_maxK1 - _minK1) / 10.0;
	real minDiff = _meanK1;
	if ((faceLayer->dotP(0) < minDiff) && (faceLayer->dotP(1) < minDiff) && (faceLayer->dotP(2) < minDiff)) {
		faceLayer->ReplaceDotP(0, 0);
		faceLayer->ReplaceDotP(1, 0);
		faceLayer->ReplaceDotP(2, 0);
	}
#endif
}
OWXFaceLayer ViewEdgeXBuilder::FindPreviousFaceLayer(const OWXFaceLayer& iFaceLayer)
{
	WXFace *previousFace = NULL;
	WOEdge *woebegin;
	real tend;
	if (iFaceLayer.order) {
		woebegin = iFaceLayer.fl->getSmoothEdge()->woea();
		tend = iFaceLayer.fl->getSmoothEdge()->ta();
	}
	else {
		woebegin = iFaceLayer.fl->getSmoothEdge()->woeb();
		tend = iFaceLayer.fl->getSmoothEdge()->tb();
	}

	// special case of EDGE_VERTEX config:
	if ((tend == 0.0) || (tend == 1.0)) {
		WVertex *previousVertex;
		if (tend == 0.0)
			previousVertex = woebegin->GetaVertex();
		else
			previousVertex = woebegin->GetbVertex();
		if (previousVertex->isBoundary()) // if it's a non-manifold vertex -> ignore
			return OWXFaceLayer(NULL, true);
		bool found = false;
		WVertex::face_iterator f = previousVertex->faces_begin();
		WVertex::face_iterator fend = previousVertex->faces_end();
		for (; (!found) && (f != fend); ++f) {
			previousFace = dynamic_cast<WXFace*>(*f);
			if ((0 != previousFace) && (previousFace != iFaceLayer.fl->getFace())) {
				vector<WXFaceLayer*> sameNatureLayers;
				previousFace->retrieveSmoothEdgesLayers(iFaceLayer.fl->nature(), sameNatureLayers);
				// don't know... Maybe should test whether this face has also a vertex_edge configuration
				if (sameNatureLayers.size() == 1) {
					WXFaceLayer *winner = sameNatureLayers[0];
					// check face mark continuity
					if (winner->getFace()->GetMark() != iFaceLayer.fl->getFace()->GetMark())
						return OWXFaceLayer(NULL, true);
					if (woebegin == winner->getSmoothEdge()->woeb()->twin())
						return OWXFaceLayer(winner, true);
					else
						return OWXFaceLayer(winner, false);
				}
			}
		}
	}
	else {
		previousFace = dynamic_cast<WXFace*>(iFaceLayer.fl->getFace()->GetBordingFace(woebegin));
		if (0 == previousFace)
			return OWXFaceLayer(NULL, true);
		// if the next face layer has either no smooth edge or no smooth edge of same nature, no next face
		if (!previousFace->hasSmoothEdges())
			return OWXFaceLayer(NULL, true);
		vector<WXFaceLayer*> sameNatureLayers;
		previousFace->retrieveSmoothEdgesLayers(iFaceLayer.fl->nature(), sameNatureLayers);
		// don't know how to deal with several edges of same nature on a single face
		if ((sameNatureLayers.empty()) || (sameNatureLayers.size() != 1)) {
			return OWXFaceLayer(NULL, true);
		}
		else {
			WXFaceLayer *winner = sameNatureLayers[0];
			// check face mark continuity
			if (winner->getFace()->GetMark() != iFaceLayer.fl->getFace()->GetMark())
				return OWXFaceLayer(NULL, true);
			if (woebegin == winner->getSmoothEdge()->woeb()->twin())
				return OWXFaceLayer(winner, true);
			else
				return OWXFaceLayer(winner, false);
		}
	}
	return OWXFaceLayer(NULL, true);
}