PrimitiveRange::PrimitiveRange(PrimitiveType type, const VertexRange& vertexRange): m_type(type), m_vertexBuffer(nullptr), m_indexBuffer(nullptr), m_start(0), m_count(0), m_base(0) { m_vertexBuffer = vertexRange.vertexBuffer(); m_start = vertexRange.start(); m_count = vertexRange.count(); }
list LinearCartesian1D_Domain::get_vertices() { list vertices; typedef LinearCartesian1D_Domain_t DomainType; typedef viennagrid::result_of::element_range<DomainType, viennagrid::vertex_tag>::type VertexRange; typedef viennagrid::result_of::iterator<VertexRange>::type VertexIterator; VertexRange range = viennagrid::elements(domain); for (VertexIterator it = range.begin(); it != range.end(); ++it) vertices.append<LinearCartesian1D_Vertex>(LinearCartesian1D_Vertex(*it)); return vertices; }
LinearSpherical3D_Vertex LinearSpherical3D_Domain::get_vertex(unsigned int index) { typedef LinearSpherical3D_VertexRange_t VertexRange; typedef viennagrid::result_of::iterator<VertexRange>::type VertexIterator; typedef LinearSpherical3D_Vertex_t::id_type VertexIDType; VertexIterator vertex = viennagrid::find_by_id(domain, VertexIDType(index)); VertexRange range = viennagrid::elements(domain); if (vertex == range.end()) { std::stringstream ss; ss << "no vertex at index " << index; throw std::out_of_range(ss.str()); } return LinearSpherical3D_Vertex(*vertex); }
void AddPartialSharedRanges(Overlap & ovrlp, // out Partition const& Prtng, int p, Part2Cell const& P2C, VertexRange const& shared_v, FacetRange const& shared_f, VtxCorr const& vtx_corr, FacetCorr const& facet_corr) { // for(int p = 0; p < (int) Prtng.NumOfPartitions(); ++p) { typedef typename FacetRange::ElementIterator RgeFacetIterator; for(RgeFacetIterator f = shared_f.FirstElement(); ! f.IsDone(); ++f) { int q = Prtng.other_partition(*f,p); // if(p > q) { // <---- unsymmetric if( (P2C(q) < P2C(p)) || (P2C(p) == P2C(q) && p > q)) { // <---- unsymmetric ovrlp[P2C(p)].facets(P2C(q)).shared().push_back(*f); // local if( q < 0) ovrlp[P2C(q)].facets(P2C(p)).shared().push_back(facet_corr(*f)); // "remote" else ovrlp[P2C(q)].facets(P2C(p)).shared().push_back(*f); // "local" } } // } PartitionsByVertex<Partition> PV(Prtng); typedef typename PartitionsByVertex<Partition>::PartitionOfVertexIterator VtxPartIterator; // for(int p = 0; p < (int) Prtng.NumOfPartitions(); ++p) { // CoarseCell P(Prtng.PartCell()); typedef typename VertexRange::ElementIterator RgeVertexIterator; for(RgeVertexIterator v = shared_v.FirstElement(); ! v.IsDone(); ++v) { for(VtxPartIterator qi = PV.begin(*v); qi != PV.end(*v); ++qi) { int q = *qi; // if(p > q) { // <---- unsymmetric if( (P2C(q) < P2C(p)) || (P2C(p) == P2C(q) && p > q)) { // <---- unsymmetric ovrlp[P2C(p)].vertices(P2C(q)).shared().push_back(*v); // local if( q < 0) ovrlp[P2C(q)].vertices(P2C(p)).shared().push_back(vtx_corr(*v)); // "remote" else ovrlp[P2C(q)].vertices(P2C(p)).shared().push_back(*v); // "local" } } } // } }
void Font::drawText(vec2 pen, vec4 color, const char* text) { uint vertexCount = 0; // Realize vertices for glyphs { const size_t length = std::strlen(text); m_vertices.resize(length * 6); for (const char* c = text; *c != '\0'; ) { const uint32 codepoint = utf8::next<const char*>(c, text + length); const Glyph* glyph = findGlyph(codepoint); if (!glyph) { glyph = findGlyph(0xfffd); if (!glyph) continue; } pen = round(pen); if (all(greaterThan(glyph->size, vec2(0.f)))) { const Rect pa(pen + glyph->bearing - vec2(0.5f), glyph->size); const Rect ta(glyph->offset + vec2(0.5f), glyph->size); m_vertices[vertexCount + 0].texcoord = ta.position; m_vertices[vertexCount + 0].position = pa.position; m_vertices[vertexCount + 1].texcoord = ta.position + vec2(ta.size.x, 0.f); m_vertices[vertexCount + 1].position = pa.position + vec2(pa.size.x, 0.f); m_vertices[vertexCount + 2].texcoord = ta.position + ta.size; m_vertices[vertexCount + 2].position = pa.position + pa.size; m_vertices[vertexCount + 3] = m_vertices[vertexCount + 2]; m_vertices[vertexCount + 4].texcoord = ta.position + vec2(0.f, ta.size.y); m_vertices[vertexCount + 4].position = pa.position + vec2(0.f, pa.size.y); m_vertices[vertexCount + 5] = m_vertices[vertexCount + 0]; vertexCount += 6; } pen += vec2(glyph->advance, 0.f); } } if (!vertexCount) return; VertexRange range = m_context.allocateVertices(vertexCount, Vertex2ft2fv::format); if (range.isEmpty()) { logError("Failed to allocate vertices for text drawing"); return; } range.copyFrom(m_vertices.data()); m_pass.setUniformState(m_colorIndex, color); m_pass.apply(); m_context.render(PrimitiveRange(TRIANGLE_LIST, range)); }
int main( int argc, char** argv ) { QApplication application(argc,argv); string inputFilename = argc > 1 ? argv[ 1 ] : examplesPath+"/samples/Al.100.vol"; int threshold = argc > 2 ? atoi( argv[ 2 ] ) : 0; int widthNum = argc > 3 ? atoi( argv[ 3 ] ) : 2; int widthDen = argc > 4 ? atoi( argv[ 4 ] ) : 1; //! [polyhedralizer-readVol] trace.beginBlock( "Reading vol file into an image." ); typedef ImageContainerBySTLVector< Domain, int> Image; Image image = VolReader<Image>::importVol(inputFilename); typedef functors::SimpleThresholdForegroundPredicate<Image> DigitalObject; DigitalObject digitalObject( image, threshold ); trace.endBlock(); //! [polyhedralizer-readVol] //! [polyhedralizer-KSpace] trace.beginBlock( "Construct the Khalimsky space from the image domain." ); KSpace ks; bool space_ok = ks.init( image.domain().lowerBound(), image.domain().upperBound(), true ); if (!space_ok) { trace.error() << "Error in the Khamisky space construction."<<endl; return 2; } trace.endBlock(); //! [polyhedralizer-KSpace] //! [polyhedralizer-SurfelAdjacency] typedef SurfelAdjacency<KSpace::dimension> MySurfelAdjacency; MySurfelAdjacency surfAdj( false ); // exterior in all directions. //! [polyhedralizer-SurfelAdjacency] //! [polyhedralizer-ExtractingSurface] trace.beginBlock( "Extracting boundary by tracking the surface. " ); typedef KSpace::Surfel Surfel; Surfel start_surfel = Surfaces<KSpace>::findABel( ks, digitalObject, 100000 ); typedef ImplicitDigitalSurface< KSpace, DigitalObject > MyContainer; typedef DigitalSurface< MyContainer > MyDigitalSurface; typedef MyDigitalSurface::ConstIterator ConstIterator; MyContainer container( ks, digitalObject, surfAdj, start_surfel ); MyDigitalSurface digSurf( container ); trace.info() << "Digital surface has " << digSurf.size() << " surfels." << endl; trace.endBlock(); //! [polyhedralizer-ExtractingSurface] //! [polyhedralizer-ComputingPlaneSize] // First pass to find biggest planes. trace.beginBlock( "Decomposition first pass. Computes all planes so as to sort vertices by the plane size." ); typedef BreadthFirstVisitor<MyDigitalSurface> Visitor; typedef ChordGenericNaivePlaneComputer<Z3,Z3::Point, DGtal::int64_t> NaivePlaneComputer; map<Surfel,unsigned int> v2size; for ( ConstIterator it = digSurf.begin(), itE= digSurf.end(); it != itE; ++it ) v2size[ *it ] = 0; int j = 0; int nb = digSurf.size(); NaivePlaneComputer planeComputer; vector<Point> layer; vector<Surfel> layer_surfel; for ( ConstIterator it = digSurf.begin(), itE= digSurf.end(); it != itE; ++it ) { if ( ( (++j) % 50 == 0 ) || ( j == nb ) ) trace.progressBar( j, nb ); Surfel v = *it; planeComputer.init( widthNum, widthDen ); // The visitor takes care of all the breadth-first traversal. Visitor visitor( digSurf, v ); layer.clear(); layer_surfel.clear(); Visitor::Size currentSize = visitor.current().second; while ( ! visitor.finished() ) { Visitor::Node node = visitor.current(); v = node.first; int axis = ks.sOrthDir( v ); Point p = ks.sCoords( ks.sDirectIncident( v, axis ) ); if ( node.second != currentSize ) { bool isExtended = planeComputer.extend( layer.begin(), layer.end() ); if ( isExtended ) { for ( vector<Surfel>::const_iterator it_layer = layer_surfel.begin(), it_layer_end = layer_surfel.end(); it_layer != it_layer_end; ++it_layer ) { ++v2size[ *it_layer ]; } layer_surfel.clear(); layer.clear(); currentSize = node.second; } else break; } layer_surfel.push_back( v ); layer.push_back( p ); visitor.expand(); } } // Prepare queue typedef PairSorted2nd<Surfel,int> SurfelWeight; priority_queue<SurfelWeight> Q; for ( ConstIterator it = digSurf.begin(), itE= digSurf.end(); it != itE; ++it ) Q.push( SurfelWeight( *it, v2size[ *it ] ) ); trace.endBlock(); //! [polyhedralizer-ComputingPlaneSize] //! [polyhedralizer-segment] // Segmentation into planes trace.beginBlock( "Decomposition second pass. Visits vertices from the one with biggest plane to the one with smallest plane." ); typedef Triple<NaivePlaneComputer, Color, pair<RealVector,double> > RoundPlane; set<Surfel> processedVertices; vector<RoundPlane*> roundPlanes; map<Surfel,RoundPlane*> v2plane; j = 0; while ( ! Q.empty() ) { if ( ( (++j) % 50 == 0 ) || ( j == nb ) ) trace.progressBar( j, nb ); Surfel v = Q.top().first; Q.pop(); if ( processedVertices.find( v ) != processedVertices.end() ) // already in set continue; // process to next vertex RoundPlane* ptrRoundPlane = new RoundPlane; roundPlanes.push_back( ptrRoundPlane ); // to delete them afterwards. v2plane[ v ] = ptrRoundPlane; ptrRoundPlane->first.init( widthNum, widthDen ); ptrRoundPlane->third = make_pair( RealVector::zero, 0.0 ); // The visitor takes care of all the breadth-first traversal. Visitor visitor( digSurf, v ); layer.clear(); layer_surfel.clear(); Visitor::Size currentSize = visitor.current().second; while ( ! visitor.finished() ) { Visitor::Node node = visitor.current(); v = node.first; Dimension axis = ks.sOrthDir( v ); Point p = ks.sCoords( ks.sDirectIncident( v, axis ) ); if ( node.second != currentSize ) { bool isExtended = ptrRoundPlane->first.extend( layer.begin(), layer.end() ); if ( isExtended ) { for ( vector<Surfel>::const_iterator it_layer = layer_surfel.begin(), it_layer_end = layer_surfel.end(); it_layer != it_layer_end; ++it_layer ) { Surfel s = *it_layer; processedVertices.insert( s ); if ( v2plane.find( s ) == v2plane.end() ) v2plane[ s ] = ptrRoundPlane; } layer.clear(); layer_surfel.clear(); currentSize = node.second; } else break; } layer_surfel.push_back( v ); layer.push_back( p ); if ( processedVertices.find( v ) != processedVertices.end() ) // surfel is already in some plane. visitor.ignore(); else visitor.expand(); } if ( visitor.finished() ) { for ( vector<Surfel>::const_iterator it_layer = layer_surfel.begin(), it_layer_end = layer_surfel.end(); it_layer != it_layer_end; ++it_layer ) { Surfel s = *it_layer; processedVertices.insert( s ); if ( v2plane.find( s ) == v2plane.end() ) v2plane[ s ] = ptrRoundPlane; } } // Assign random color for each plane. ptrRoundPlane->second = Color( rand() % 192 + 64, rand() % 192 + 64, rand() % 192 + 64, 255 ); } trace.endBlock(); //! [polyhedralizer-segment] //! [polyhedralizer-lsf] for ( vector<RoundPlane*>::iterator it = roundPlanes.begin(), itE = roundPlanes.end(); it != itE; ++it ) { NaivePlaneComputer& computer = (*it)->first; RealVector normal; double mu = LSF( normal, computer.begin(), computer.end() ); (*it)->third = make_pair( normal, mu ); } //! [polyhedralizer-lsf] //! [polyhedralizer-projection] map<Surfel, RealPoint> coordinates; for ( map<Surfel,RoundPlane*>::const_iterator it = v2plane.begin(), itE = v2plane.end(); it != itE; ++it ) { Surfel v = it->first; RoundPlane* rplane = it->second; Point p = ks.sKCoords( v ); RealPoint rp( (double)p[ 0 ]/2.0, (double)p[ 1 ]/2.0, (double)p[ 2 ]/2.0 ); double mu = rplane->third.second; RealVector normal = rplane->third.first; double lambda = mu - rp.dot( normal ); coordinates[ v ] = rp + lambda*normal; } typedef vector<Surfel> SurfelRange; map<Surfel, RealPoint> new_coordinates; for ( ConstIterator it = digSurf.begin(), itE= digSurf.end(); it != itE; ++it ) { Surfel s = *it; SurfelRange neighbors; back_insert_iterator<SurfelRange> writeIt = back_inserter( neighbors ); digSurf.writeNeighbors( writeIt, *it ); RealPoint x = RealPoint::zero; for ( SurfelRange::const_iterator its = neighbors.begin(), itsE = neighbors.end(); its != itsE; ++its ) x += coordinates[ *its ]; new_coordinates[ s ] = x / neighbors.size(); } //! [polyhedralizer-projection] //! [polyhedralizer-MakeMesh] typedef unsigned int Number; typedef Mesh<RealPoint> MyMesh; typedef MyMesh::MeshFace MeshFace; typedef MyDigitalSurface::FaceSet FaceSet; typedef MyDigitalSurface::VertexRange VertexRange; map<Surfel, Number> index; // Numbers all vertices. Number nbv = 0; MyMesh polyhedron( true ); // Insert all projected surfels as vertices of the polyhedral surface. for ( ConstIterator it = digSurf.begin(), itE= digSurf.end(); it != itE; ++it ) { polyhedron.addVertex( new_coordinates[ *it ] ); index[ *it ] = nbv++; } // Define faces of the mesh. Outputs closed faces. FaceSet faces = digSurf.allClosedFaces(); for ( typename FaceSet::const_iterator itf = faces.begin(), itf_end = faces.end(); itf != itf_end; ++itf ) { MeshFace mface( itf->nbVertices ); VertexRange vtcs = digSurf.verticesAroundFace( *itf ); int i = 0; for ( typename VertexRange::const_iterator itv = vtcs.begin(), itv_end = vtcs.end(); itv != itv_end; ++itv ) { mface[ i++ ] = index[ *itv ]; } polyhedron.addFace( mface, Color( 255, 243, 150, 255 ) ); } //! [polyhedralizer-MakeMesh] //! [polyhedralizer-visualization] typedef Viewer3D<Space,KSpace> MyViewer3D; MyViewer3D viewer( ks ); viewer.show(); bool isOK = polyhedron >> "test.off"; bool isOK2 = polyhedron >> "test.obj"; viewer << polyhedron; viewer << MyViewer3D::updateDisplay; application.exec(); //! [polyhedralizer-visualization] //! [polyhedralizer-freeMemory] for ( vector<RoundPlane*>::iterator it = roundPlanes.begin(), itE = roundPlanes.end(); it != itE; ++it ) delete *it; //! [polyhedralizer-freeMemory] if (isOK && isOK2) return 0; else return 1; }