Exemple #1
0
void create_subdivided_face(int sdRes, int nV, double *uvs, double *itv, int Tidx, MFloatArray &uA, MFloatArray &vA, MIntArray &uvIdx)
{
    HDS hds;
    
    hds.V.setDims(2, nV); memcpy(&hds.V.v[0], uvs, 2*nV*sizeof(double));
    hds.nFV.setDims(1, 1); hds.nFV[0] = nV;

    hds.tip.setDims(1, nV); 
    for (size_t k=0; k<nV; k++) 
    {
        hds.tip[k] = k;
    }
    finalize_HDS(hds);
    
    size_t nHE = hds.nHE(), nIHE = hds.nIHE();⟵
    hds.T.setDims(1, nHE);
    hds.itv.setDims(1, nHE);

    memset(&hds.T.v[0], 0, nHE*sizeof(bool)); if (nV==5) hds.T[Tidx] = 1;
    memcpy(&hds.itv.v[0], itv, nV*sizeof(double));

    // border halfedge tags
    for (size_t k=nIHE; k<nHE; k++) 
    {
        hds.itv[k] = hds.itv[hds.twin[k]];
    }
    
    TCC_MAX::linear_subdivide(hds, sdRes);
    
    int sd_nV = hds.nV();
    int sd_nIHE = hds.nIHE();

    uA.setLength(sd_nV);
    vA.setLength(sd_nV);
    for (int k=0; k<sd_nV; k++)
    {
        uA[k] = hds.V[2*k+0];
        vA[k] = hds.V[2*k+1];
    }
    
    uvIdx.setLength(sd_nIHE);
    for (int k=0; k<sd_nIHE; k++)
    {
        uvIdx[k]=hds.tip[k];
    }
}
Exemple #2
0
void load_from_hds(HDS &hds, MFloatPointArray &points, MIntArray &nFV, MIntArray &F)
{
    size_t nV   = hds.nV();
    size_t nF   = hds.nF();
    size_t nIHE = hds.nIHE();
    
    points.setLength(nV);
    for (size_t k=0; k<nV; k++) 
    {
        points[k](0) = hds.V[3*k+0];
        points[k](1) = hds.V[3*k+1];
        points[k](2) = hds.V[3*k+2];
    }
    
    nFV.setLength(nF);
    for (size_t k=0; k<nF; k++) nFV[k] = hds.nFV[k];
    
    F.setLength(nIHE);
    for (size_t k=0; k<nIHE; k++) F[k] = hds.tip[k];
}
Exemple #3
0
void test_HalfedgeDS_default() {
    // Simple instantiation of the default halfedge data structure.
    typedef CGAL_HALFEDGEDS_DEFAULT<Dummy_traits_2> HDS;
    typedef CGAL::HalfedgeDS_decorator<HDS> Decorator;
    HDS hds;
    Decorator D(hds);

    D.create_loop();
    assert( hds.size_of_vertices() == 1);
    assert( hds.size_of_halfedges() == 2);
    assert( hds.size_of_faces() == 2);
    assert( D.is_valid( false, 3));
    D.make_hole( hds.halfedges_begin()->opposite());
    hds.normalize_border();
    assert( hds.size_of_border_halfedges() == 1);
    assert( hds.size_of_border_edges() == 1);
    assert( D.is_valid( false, 4));
    D.fill_hole( hds.halfedges_begin()->opposite());
    hds.normalize_border();
    assert( hds.size_of_border_halfedges() == 0);
    assert( hds.size_of_border_edges() == 0);
    assert( D.is_valid( false, 4));

    HDS hds2(hds); // copy constructor.
    Decorator D2(hds2);
    assert( D2.is_valid( false, 4));

    hds = hds2; // assignment.
    assert( D.is_valid( false, 4));

    typedef HDS::Halfedge_iterator Halfedge_iterator;
    Halfedge_iterator i = hds.halfedges_begin();
    assert(!(i == hds.halfedges_end()));
}
Exemple #4
0
void test_HalfedgeDS_polyhedron_default() {
    // Simple instantiation of the default for polyhedrons.
    typedef CGAL_HALFEDGEDS_DEFAULT< Dummy_traits_3,
        CGAL::Polyhedron_items_3> HDS;
    typedef HDS::Vertex           Vertex;
    typedef HDS::Halfedge         Halfedge;
    typedef HDS::Face             Face;
    typedef Halfedge::Base        HBase;

    HDS hds;
    hds.vertices_push_back( Vertex());
    hds.edges_push_back( Halfedge(), Halfedge());
    hds.faces_push_back( Face());
    hds.halfedges_begin()->HBase::set_face( hds.faces_begin());
    assert( hds.size_of_vertices() == 1);
    assert( hds.size_of_halfedges() == 2);
    assert( hds.size_of_faces() == 1);
    hds.normalize_border();
    assert( hds.size_of_border_halfedges() == 1);
    assert( hds.size_of_border_edges() == 1);
    typedef HDS::Halfedge_iterator Halfedge_iterator;
    Halfedge_iterator i = hds.halfedges_begin();
    assert(!(i == hds.halfedges_end()));
}
Exemple #5
0
 void operator()(HDS & hds)
 {
   next_index = hds.size_of_vertices();
   builder = new Builder(hds, true);
 }
Exemple #6
0
void test_HalfedgeDS_decorator() {
    // Simple instantiation of the default halfedge data structure.
    typedef CGAL_HALFEDGEDS_DEFAULT<Dummy_traits_2>  HDS;
    typedef CGAL::HalfedgeDS_decorator<HDS>          Decorator;
    typedef HDS::Halfedge_handle                     Halfedge_handle;
    typedef HDS::Face_handle                         Face_handle;
    HDS hds;
    Decorator  decorator(hds);
    // Check create single loop.
    Halfedge_handle h = decorator.create_loop();
    hds.normalize_border();
    assert( hds.size_of_vertices() == 1);
    assert( hds.size_of_halfedges() == 2);
    assert( hds.size_of_faces() == 2);
    assert( decorator.is_valid( false, 4));

    // Restart with open segment.
    hds.clear();
    hds.normalize_border();
    assert( decorator.is_valid( false, 4));
    h = decorator.create_segment();
    assert( hds.size_of_vertices() == 2);
    assert( hds.size_of_halfedges() == 2);
    assert( hds.size_of_faces() == 1);
    assert( decorator.is_valid( false, 4));

    // Create border edge and check normalization.
    decorator.set_face( h->opposite(), Face_handle());
    hds.normalize_border();
    assert( hds.size_of_border_halfedges() == 1);
    assert( hds.size_of_border_edges() == 1);
    assert( decorator.normalized_border_is_valid());
    decorator.set_face( h->opposite(), h->face());
    hds.normalize_border();
    assert( hds.size_of_border_halfedges() == 0);
    assert( hds.size_of_border_edges() == 0);
    assert( decorator.is_valid( false, 4));

    // Extend edge to two triangles.
    Halfedge_handle g = decorator.split_vertex( h, h);
    assert( decorator.is_valid( false, 4));
    assert( h != g);
    assert( h->next()->next() == g);
    assert( h == g->next()->next());
    assert( h->opposite() == g->next());
    assert( g->opposite() == h->next());
    Halfedge_handle g2 = decorator.split_face(h->opposite(),g->opposite());
    assert( decorator.is_valid( false, 4));
    assert( h->opposite()->next() == g2);
    assert( g2->next() == g);
    decorator.split_vertex( g2, g->opposite());
    assert( decorator.is_valid( false, 4));
    assert( g->next()->next()->next()->next() == g);
    Halfedge_handle g3 = 
        decorator.split_face( g2->next()->opposite(), h);
    assert( decorator.is_valid( false, 4));
    assert( g->next()->next()->next()->next() == g);
    assert( h->next()->next()->next() == h);
    assert( g3->next()->next()->next() == g3);
    assert( g3->next() == g->opposite());
    assert( g3->opposite()->next() == g2->opposite());
    assert( g3->opposite() == h->next());

    // Edge flip within the triangle.
    Halfedge_handle g4 = decorator.flip_edge( g3);
    assert( decorator.is_valid( false, 4));
    assert( g4 == g3);
    assert( g3->next()->next() == g2->opposite());
    assert( g3->opposite()->next() == h);
    assert( g->next()->next()->next()->next() == g);
    assert( h->next()->next()->next() == h);
    assert( g3->next()->next()->next() == g3);

    // Reverse face orientation.
    decorator.inside_out();
    assert( decorator.is_valid( false, 4));
    decorator.inside_out();
    assert( decorator.is_valid( false, 4));

    // Check hole manipulations.
    decorator.make_hole(g);
    hds.normalize_border();
    assert( hds.size_of_border_halfedges() == 4);
    assert( hds.size_of_border_edges() == 4);
    assert( decorator.is_valid( false, 4));

    // Reverse face orientation, deal also with the hole..
    decorator.inside_out();
    assert( decorator.is_valid( false, 3));
    hds.normalize_border();
    assert( decorator.is_valid( false, 4));

    // Check add_face_to_border.
    hds.clear();
    h = decorator.create_loop();
    decorator.make_hole( h->opposite());
    hds.normalize_border();
    assert( decorator.is_valid( false, 4));
    decorator.add_face_to_border( h->opposite(), h->opposite());
    assert( hds.size_of_halfedges() == 4);
    assert( hds.size_of_faces() == 2);
    assert( decorator.is_valid( false, 3));
}
Exemple #7
0
void test_HalfedgeDS_decorator3() {
    // Simple instantiation of the default halfedge data structure.
    typedef CGAL::HalfedgeDS_default<Dummy_traits_2>  HDS;
    typedef CGAL::HalfedgeDS_decorator<HDS>          Decorator;

    CGAL_USE_TYPE(HDS::Halfedge_handle);
    CGAL_USE_TYPE(HDS::Face_handle);

    HDS hds;

    Build_triangle<HDS> modifier(0,0);
    modifier(hds);
    modifier.x_=33;
    modifier.y_=33;
    modifier(hds);


    Decorator decorator(hds);
    decorator.keep_largest_connected_components(1);

    hds.normalize_border();

    assert( hds.size_of_vertices() == 4);
    assert( hds.size_of_halfedges() == 10);
    assert( hds.size_of_faces() == 2);
    assert( decorator.is_valid( false, 4));

    decorator.vertices_erase(hds.vertices_begin());
    decorator.vertices_erase(hds.vertices_begin(), hds.vertices_end());

    decorator.faces_erase(hds.faces_begin());
    decorator.faces_erase(hds.faces_begin(), hds.faces_end());

    assert( hds.size_of_vertices() == 0);
    assert( hds.size_of_halfedges() == 10);
    assert( hds.size_of_faces() == 0);

}
Exemple #8
0
MStatus TCC::createSubdividedMesh(int sdRes, int sdRefRes, MFnMesh &srcMesh, TCCData &tccData, MDataHandle outMeshHandle, float lineThickness, MStatus& stat)
{   
    HDS hds;
    bool shouldCreateUVs = true;
    
    size_t nV = srcMesh.numVertices();
    size_t nF = srcMesh.numPolygons();
    size_t nIHE = tccData.F.length();
    
    bool consistentSizes= (tccData.pole.length()==nV) && (tccData.T.length()==nIHE) && (tccData.itv.length()==nIHE) & (tccData.corner.length()==nV);
    
    if ((nV==0)||(nF==0)||(!consistentSizes)) return MS::kFailure;

    MFloatArray uArray, vArray, sc_uArray, sc_vArray;
    MIntArray uvIdx;
    if (shouldCreateUVs)
    {
        createUVset(tccData, sdRes, uArray, vArray, sc_uArray, sc_vArray, uvIdx, lineThickness);
    }
    
    
    MFloatPointArray points;
    srcMesh.getPoints(points);
    
    store_in_hds(hds, points, tccData.nFV, tccData.F);     // convert to HDS

    finalize_HDS(hds);
    size_t nHE = hds.nHE();

    hds.T.setDims(1, nHE);
    hds.itv.setDims(1, nHE);
    hds.corner.setDims(1, nV);
    
    // interior halfedge tags
    for (size_t k=0; k<nV; k++) 
    {
        hds.corner[k] = tccData.corner[k];
    }

    // interior halfedge tags
    for (size_t k=0; k<nIHE; k++) 
    {
        hds.T[k] = tccData.T[k];
        hds.itv[k] = tccData.itv[k];
    }
    
    // border halfedge tags
    for (size_t k=nIHE; k<nHE; k++) 
    {
        hds.T[k] = false;
        hds.itv[k] = hds.itv[hds.twin[k]];
    }
        
    TCC_MAX::subdivide(hds, sdRes);
    
    if (sdRefRes>0)
    {
        HDS hds2;
        copy_HDS(hds, hds2);
        TCC_MAX::subdivide(hds2, sdRefRes);
        memcpy(&hds.V[0], &hds2.V[0], hds.V.size() * sizeof(double));
    }
    

    
    MObject outMeshObj = outMeshHandle.asMesh();
    MFnMesh outMeshFn(outMeshObj);
    
    // if no topology change necessary, just update points!
    if ( (outMeshFn.numFaceVertices() == hds.nIHE()) && (outMeshFn.numPolygons() == hds.nF()) )
    {
        size_t nV   = hds.nV();
        points.setLength(nV);
        for (size_t k=0; k<nV; k++) 
        {
            points[k](0) = hds.V[3*k+0];
            points[k](1) = hds.V[3*k+1];
            points[k](2) = hds.V[3*k+2];
        }
        stat = outMeshFn.setPoints(points); McheckErr(stat, "ERROR creating outputData");
        
        if (shouldCreateUVs)
        {
            MString uvSet = "UnitPatchUVs";
            MString sc_uvSet = "ScaledPatchUVs";
            stat = outMeshFn.setUVs(uArray, vArray, &uvSet); McheckErr(stat, "ERROR setting UVs");
            stat = outMeshFn.setUVs(sc_uArray, sc_vArray, &sc_uvSet); McheckErr(stat, "ERROR setting UVs");
        }
        
        return MS::kSuccess;
    }

    
    // Have to update connectivity and geometry

    load_from_hds(hds, points, tccData.nFV, tccData.F);

    nV = points.length();
    nF = tccData.nFV.length();
    
    MFnMeshData dataCreator;
    MObject newOutputData = dataCreator.create(&stat); McheckErr(stat, "ERROR creating outputData");
    MFnMesh newOutMeshFn;
    
    MObject newMesh;
    
    newMesh = newOutMeshFn.create(nV, nF, points, tccData.nFV, tccData.F, newOutputData, &stat); McheckErr(stat, "ERROR in MFnMesh.create\n");

    if (shouldCreateUVs)
    {
        MString uvSet = "UnitPatchUVs";
        MString sc_uvSet = "ScaledPatchUVs";
        
        uvSet = newOutMeshFn.createUVSetDataMeshWithName(uvSet, &stat); McheckErr(stat, "ERROR creating UVset");
        stat = newOutMeshFn.clearUVs(&uvSet);
        stat = newOutMeshFn.setUVs(uArray, vArray, &uvSet); McheckErr(stat, "ERROR setting UVs");
        stat = newOutMeshFn.assignUVs(tccData.nFV, uvIdx, &uvSet); McheckErr(stat, "ERROR assigning UVs");
        
        sc_uvSet = newOutMeshFn.createUVSetDataMeshWithName(sc_uvSet, &stat); McheckErr(stat, "ERROR creating UVset");
        stat = newOutMeshFn.clearUVs(&sc_uvSet);
        stat = newOutMeshFn.setUVs(sc_uArray, sc_vArray, &sc_uvSet); McheckErr(stat, "ERROR setting UVs");
        stat = newOutMeshFn.assignUVs(tccData.nFV, uvIdx, &sc_uvSet); McheckErr(stat, "ERROR assigning UVs");
    }
    
    
    if (stat == MS::kSuccess)
    {
        outMeshHandle.set(newOutputData);
    }
    
    
    return MS::kSuccess;
}