Пример #1
0
/**
 * \return Number of segments. The number of segments equals the
 *      number of vertices for a closed polyline and one less for
 *      an open polyline.
 */
int RPolyline::countSegments() const {
    if (closed) {
        return countVertices();
    }
    else {
        return countVertices() - 1;
    }
}
Пример #2
0
void
countVertices(MeshGroup const & mg, long & num_vertices)
{
  for (MeshGroup::MeshConstIterator mi = mg.meshesBegin(); mi != mg.meshesEnd(); ++mi)
    num_vertices += (*mi)->numVertices();

  for (MeshGroup::GroupConstIterator ci = mg.childrenBegin(); ci != mg.childrenEnd(); ++ci)
    countVertices(**ci, num_vertices);
}
Пример #3
0
void RPolyline::print(QDebug dbg) const {
    dbg.nospace() << "RPolyline(";
    RShape::print(dbg);
    dbg.nospace() << ", ";
    dbg.nospace() << "vertices: " << countVertices() << ", ";
    QList<QSharedPointer<RShape> > sub = getExploded();
    QList<QSharedPointer<RShape> >::iterator it;
    for (it=sub.begin(); it!=sub.end(); ++it) {
        dbg.nospace() << "\n" << *it->data() << ", ";
    }
    dbg.nospace() << ")";
}
Пример #4
0
std::vector<uint> sefield::TetMesh::getVertexPermutation(void)
{
	uint nverts = countVertices();

	// Return a copy of this vector
	std::vector<uint> vert_ret = std::vector<uint>(nverts);

	for (uint i = 0; i < nverts; ++i)
	{
		vert_ret[i] = pVertexPerm[i];
	}

	return vert_ret;
}
Пример #5
0
RBox RPolyline::getBoundingBox() const {
    RBox ret;

    if (countVertices()==1) {
        ret = RBox(vertices.at(0), vertices.at(0));
    }

    QList<QSharedPointer<RShape> > sub = getExploded();
    QList<QSharedPointer<RShape> >::iterator it;
    for (it=sub.begin(); it!=sub.end(); ++it) {
        RBox bb = (*it)->getBoundingBox();
        ret.growToInclude(bb);
    }

    return ret;
}
Пример #6
0
void
countSubents()
{
    AcBr::ErrorStatus returnValue = AcBr::eOk;
    Acad::ErrorStatus acadReturnValue = eOk;

    // Get the subentity path for a brep
	AcDbFullSubentPath subPath(kNullSubent);
	acadReturnValue = selectEntity(AcDb::kNullSubentType, subPath);
	if (acadReturnValue != eOk) {
		acutPrintf(ACRX_T("\n Error in getPath: %d"), acadReturnValue);
		return;
	}

	// Make a brep entity to access the solid
	AcBrBrep brepEntity;
	returnValue = ((AcBrEntity*)&brepEntity)->set(subPath);
	if (returnValue != AcBr::eOk) {
		acutPrintf(ACRX_T("\n Error in AcBrBrep::set:"));
		errorReport(returnValue);
		return;
	}

	// count the unique complexes in the brep
	returnValue = countComplexes(brepEntity);
	if (returnValue != AcBr::eOk) {
		acutPrintf(ACRX_T("\n Error in countComplexes:"));
		errorReport(returnValue);
		return;
	}

	// count the unique shells in the brep
	returnValue = countShells(brepEntity);
	if (returnValue != AcBr::eOk) {
		acutPrintf(ACRX_T("\n Error in countShells:"));
		errorReport(returnValue);
		return;
	}

	// count the unique faces in the brep
	returnValue = countFaces(brepEntity);
	if (returnValue != AcBr::eOk) {
		acutPrintf(ACRX_T("\n Error in countFaces:"));
		errorReport(returnValue);
		return;
	}

	// count the unique edges in the brep
	returnValue = countEdges(brepEntity);
	if (returnValue != AcBr::eOk) {
		acutPrintf(ACRX_T("\n Error in countEdges:"));
		errorReport(returnValue);
		return;
	}

	// count the unique vertices in the brep
	returnValue = countVertices(brepEntity);
	if (returnValue != AcBr::eOk) {
		acutPrintf(ACRX_T("\n Error in countVertices:"));
		errorReport(returnValue);
		return;
	}

	return;
}
Пример #7
0
bool NTriangulation::simplifyToLocalMinimum(bool perform) {
    BoundaryComponentIterator bit;
    unsigned long nTriangles;
    unsigned long iTriangle;
    // unsigned long nEdges;
    // unsigned long iEdge;
    // std::deque<NEdgeEmbedding>::const_iterator embit, embbeginit, embendit;

    bool changed = false;   // Has anything changed ever (for return value)?
    bool changedNow = true; // Did we just change something (for loop control)?

    { // Begin scope for change event span.
        ChangeEventSpan span(this);

        while (changedNow) {
            changedNow = false;
            ensureSkeleton();

            // Crush edges if we can.
            if (countVertices() > components().size() &&
                    countVertices() > boundaryComponents_.size()) {
                for (NEdge* edge : edges())
                    if (collapseEdge(edge, true, perform)) {
                        changedNow = changed = true;
                        break;
                    }
                if (changedNow) {
                    if (perform)
                        continue;
                    else
                        return true;
                }
            }

            // Look for internal simplifications.
            for (NEdge* edge : edges()) {
                if (threeTwoMove(edge, true, perform)) {
                    changedNow = changed = true;
                    break;
                }
                if (twoZeroMove(edge, true, perform)) {
                    changedNow = changed = true;
                    break;
                }
                if (twoOneMove(edge, 0, true, perform)) {
                    changedNow = changed = true;
                    break;
                }
                if (twoOneMove(edge, 1, true, perform)) {
                    changedNow = changed = true;
                    break;
                }
            }
            if (changedNow) {
                if (perform)
                    continue;
                else
                    return true;
            }
            for (NVertex* vertex : vertices())
                if (twoZeroMove(vertex, true, perform)) {
                    changedNow = changed = true;
                    break;
                }
            if (changedNow) {
                if (perform)
                    continue;
                else
                    return true;
            }

            // Look for boundary simplifications.
            if (hasBoundaryTriangles()) {
                for (bit = boundaryComponents_.begin();
                        bit != boundaryComponents_.end(); bit++) {
                    // Run through triangles of this boundary component looking
                    // for shell boundary moves.
                    nTriangles = (*bit)->countTriangles();
                    for (iTriangle = 0; iTriangle < nTriangles; iTriangle++) {
                        if (shellBoundary((*bit)->triangle(iTriangle)->
                                front().tetrahedron(),
                                true, perform)) {
                            changedNow = changed = true;
                            break;
                        }
                    }
                    if (changedNow)
                        break;
                }
                if (changedNow) {
                    if (perform)
                        continue;
                    else
                        return true;
                }
            }
        }
    } // End scope for change event span.

    return changed;
}
Пример #8
0
void sefield::TetMesh::axisOrderElements(uint opt_method, std::string const & opt_file_name)
{

	// Now this method provides a choice between Stefan and Robert's method
	// and the new method by Iain. The original method is fast and suffices for
	// simple geometries, Iain's method is superior and important for complex
	// geometries, but slow.

	if (opt_file_name != "")
	{
		std::fstream opt_file;

	    opt_file.open(opt_file_name.c_str(),
	                std::fstream::in | std::fstream::binary);
	    opt_file.seekg(0);

	    uint nelems = 0;
	    opt_file.read((char*)&nelems, sizeof(uint));
	    if (pElements.size() != nelems) {
	        std::ostringstream os;
	        os << "optimal data mismatch with simulator parameters: sefield::Tetmesh::nelems, ";
	        os << nelems << ":" << pElements.size();
	        throw steps::ArgErr(os.str());
	    }
	    opt_file.read((char*)pVertexPerm, sizeof(uint) * nelems);

	    VertexElementPVec elements_temp = pElements;

	    for (uint vidx = 0; vidx < nelems; ++vidx)
	    {
	    	VertexElementP vep = elements_temp[vidx];
	    	// sanity check
	    	assert(vep->getIDX() == vidx);
	    	uint new_idx = pVertexPerm[vidx];
	    	pElements[new_idx] = vep;
	    }

	    reindexElements();
	    reordered();
	    opt_file.close();
	    return;

	}


	if (opt_method == 2)
	{
		// / / / / / / / / / / / /  / / NEW / / / / / / / / / / / / / / / / / / //

		// LOOPING OVER ALL VERTICES, APPLYING THE WALK METHOD AND FINDING WHICH
		// STARTING VERTEX GIVES THE LOWEST MATRIX WIDTH.

		uint pNVerts = pElements.size();

		// the best vertex(narrowest width)
		uint bestone = 0;
		uint bestwidth = pNVerts;

		std::vector<VertexElement*> orig_indices = pElements;

        stringstream ss;
        ss << "\nFinding optimal vertex indexing. This can take some time...";
        cout << ss.str() << endl;
		for (uint vidx = 0; vidx < pNVerts; ++vidx)
		{
			set<VertexElement*> verteleset = set<VertexElement*>();
			vector<VertexElement*> vertelevec = vector<VertexElement*>();
			queue<VertexElement*> vertelqueue = queue<VertexElement*>();

			verteleset.insert(orig_indices[vidx]);
			vertelevec.push_back(orig_indices[vidx]);
			uint ve0ncons = orig_indices[vidx]->getNCon();
			VertexElement ** ve0neighbs = orig_indices[vidx]->getNeighbours();

			fill_ve_vec(verteleset, vertelevec, vertelqueue, ve0ncons, ve0neighbs);
			pElements.clear();

			vector<VertexElement*>::iterator vertele_end = vertelevec.end();
			uint ielt = 0;

			for (vector<VertexElement*>::iterator vertele = vertelevec.begin(); vertele != vertele_end; ++vertele)
			{
				pElements.push_back(*vertele);
				pVertexPerm[(*vertele)->getIDX()]=ielt;
				ielt++;
			}

			// Note: this will reorder the vertex indices as we go- not a problem in this loop
			// but they must be reset for the final index setting to work
			reindexElements();

			uint maxdi = 0;
			for (int iv = 0; iv < pNVerts; ++iv)
			{
				VertexElement* ve = getVertex(iv);
				int ind = ve->getIDX();

				for (int i = 0; i < ve->getNCon(); ++i)
				{
					int inbr = ve->nbrIdx(i);
					int di = ind - inbr;
					if (di < 0)
					{
						di = -di;
					}
					if (di > maxdi)
					{
						maxdi = di;
					}
				}
			}
			if (maxdi < bestwidth)
			{
				bestone = vidx;
				bestwidth = maxdi;
				//cout << "\nOriginal vertex "<< vidx << " gives banded matrix half-width " << maxdi;
			}
		}

		// reset the vertex indices to their original value: important
		for (uint v = 0; v < pNVerts; ++v)
		{
			orig_indices[v]->setIDX(v);
		}

		set<VertexElement*> verteleset = set<VertexElement*>();
		vector<VertexElement*> vertelevec = vector<VertexElement*>();
		queue<VertexElement*> vertelqueue = queue<VertexElement*>();

		verteleset.insert(orig_indices[bestone]);
		vertelevec.push_back(orig_indices[bestone]);
		uint ve0ncons = orig_indices[bestone]->getNCon();
		VertexElement ** ve0neighbs = orig_indices[bestone]->getNeighbours();

		fill_ve_vec(verteleset, vertelevec, vertelqueue, ve0ncons, ve0neighbs);
		pElements.clear();

		vector<VertexElement*>::iterator vertele_end = vertelevec.end();
		uint ielt = 0;
		for (vector<VertexElement*>::iterator vertele = vertelevec.begin(); vertele != vertele_end; ++vertele)
		{
			pElements.push_back(*vertele);
			pVertexPerm[(*vertele)->getIDX()]=ielt;
			ielt++;
		}
	}
    // / / / / / / / / / / / /  / / / / / / / / / / / / / / / / / / / / / / //

	else if (opt_method == 1)
	{
		/*

		THIS ORIGINAL CODE REPLACED WITH NEW 'WALKING' METHOD. A DRAMATIC
		REDUCTION IN BAND HALF-WIDTHS FOR COMPLEX 3D MESHES.
		This is not the end of the story: TODO investigate whether reordering
		a vertices neighbour's for the queue by distance will improve again.
		 */
		std::vector<double> com = centerOfMass();
		double ** m = new double*[3];
		for (uint i = 0; i < 3; i++)
		{
			m[i] = new double[3];
			m[i][0] = 0.0;
			m[i][1] = 0.0;
			m[i][2] = 0.0;
		}

		for (uint ivert = 0; ivert < countVertices(); ivert++)
		{
			VertexElement* ve = getVertex(ivert);
			double x = ve->getX() - com[0];
			double y = ve->getY() - com[1];
			double z = ve->getZ() - com[2];

			m[0][0] += x * x;
			m[0][1] += x * y;
			m[0][2] += x * z;

			m[1][0] += y * x;
			m[1][1] += y * y;
			m[1][2] += y * z;

			m[2][0] += z * x;
			m[2][1] += z * y;
			m[2][2] += z * z;
		}

		uint iret;
		double gamma;
		double evec[3];
		mainEvec(3, m, &iret, &gamma, evec);
		if (iret != 1)
		{
			cout << "\nWarning - eigenvalue faliure " << endl;
		}

		for (uint i = 0; i < 3; i++)
		{
			delete[] m[i];
		}
		delete[] m;

		double vx = evec[0];
		double vy = evec[1];
		double vz = evec[2];
		vx += 1.e-8;
		vy += 1.e-9;
		vz += 1.e-10;
		stringstream ss;
		ss << "aligning to axis " << vx << " " << vy << " " << vz << endl;
		//cout << ss.str();

		map<double, VertexElement*> hm;
		//vector<double> da;
		for (uint ielt = 0; ielt < countVertices(); ielt++)
		{
			VertexElement * ve = getVertex(ielt);
			double d = vx * ve->getX() + vy * ve->getY() + vz * ve->getZ();

			hm[d] = ve;
			//da.push_back(d);
		}

		//sort(da.begin(), da.end());

		pElements.clear();
		uint ielt = 0;
		map<double, VertexElement*>::const_iterator iter = hm.begin();

		while (iter != hm.end())
		{
			double d = iter->first;
			pElements.push_back(hm[d]);
			++iter;

			// pVertexPerm[i] contains the new index in the elements array
			// for the vertex that was originally at index i
			pVertexPerm[hm[d]->getIDX()] = ielt;
			ielt++;
		}
	}
	else
	{
		std::ostringstream os;
		os << "Unknown optimization method.\n";
		throw steps::ArgErr(os.str());
	}


    reindexElements();
    reordered();

}