GeometryCollective / boundary-first-flattening

MIT License
768 stars 96 forks source link

Using the `flatten` method in the `BFF` class, preserving area. #23

Closed lukkio88 closed 5 years ago

lukkio88 commented 6 years ago

Hi,

How is the following method:

    // computes automatic flattening with minimal area distortion
    //    -boundaryData stores either the target angles at boundary vertices (if
    //     givenScaleFactors is false) -OR- the target scale factors (if givenScaleFactors
    //     is true)
    // (resulting flattening is stored in Corner::uv for each corner of this->mesh)
    void flatten(DenseMatrix& boundaryData, bool givenScaleFactors);

The kind of flattening I'm looking for is the one that reduces area distorsion. So I would load for example an .obj file, store it into a Mesh data structure (the one provided by your tool which is an HalfEdge data structure), later instantiate an BFF object. Now I'm stuck in figuring out how to use the flatten method, can you please guide me through it maybe with some pseudocode?

Regards

rohan-sawhney commented 6 years ago

Yes, you should call the flatten with boundaryData initialized to 0 and givenScaleFactors set to true once you've initialized a BFF object. That should give you a map with minimal area distortion.

lukkio88 commented 6 years ago

I suppose, but I might be wrong, the size of boundaryData would be num_vertices*num_vertices. Is it correct?

rohan-sawhney commented 6 years ago

boundaryData is a vector of size #(boundary vertices). Here's an example of how to initialize boundaryData: https://github.com/GeometryCollective/boundary-first-flattening/blob/23d8448a817f5175ebffd79f233076444b3a8d5e/viewer/src/Viewer.cpp#L1455

lukkio88 commented 6 years ago

Ah ok, so for example if I had a grid of quads made of 5x5 vertices, the data->bN would be 16, correct?

rohan-sawhney commented 6 years ago

Yes, that's right

lukkio88 commented 6 years ago

Thank you, very last question. After the flattening, where will the result be stored?

rohan-sawhney commented 6 years ago

No worries, feel free to ask more questions :). The flattening is stored here: https://github.com/GeometryCollective/boundary-first-flattening/blob/23d8448a817f5175ebffd79f233076444b3a8d5e/mesh/include/Corner.h#L14

lukkio88 commented 6 years ago

Hi, Is the following snippet correct to create a BFF object? For some reason after the I get a segmentation fault when I try to instantiate one object.

#include <Bff.h>
#include <MeshIO.h>

int main(int argc, char** argv) {

    std::ifstream ifs("./test_mesh.obj");
    std::stringstream ss_content;
    std::string content;
    std::istringstream iss_content;

    if(ifs) {
        std::cout << "Reading file!" << std::endl;
        ss_content << ifs.rdbuf();
        content = ss_content.str();
        iss_content = std::istringstream(content);
    }

    ifs.close();

    std::cout << "Mesh read!" << std::endl;

    Mesh test_mesh;

    std::cout << "Object mesh created" << std::endl;

    MeshIO::read(iss_content,test_mesh);

    std::cout << "Content obj used to initialize the mesh" << std::endl;

    BFF flattening_module = BFF(test_mesh);

    return 0;

}
rohan-sawhney commented 6 years ago

I'm not quite sure. Try initializing the BFF object like "BFF flattening_module(test_mesh)" though I'm not sure if it'll solve the problem.

lukkio88 commented 6 years ago

Nope, that does not work. Is there any way I can check if the loaded mesh is valid? The obj I'm trying to load is the following:

v -0.500000 -0.500000 0.500000
v 0.500000 -0.500000 0.500000
v -0.500000 0.500000 0.500000
v 0.500000 0.500000 0.500000
v -0.500000 0.500000 -0.500000
v 0.500000 0.500000 -0.500000
v -0.500000 -0.500000 -0.500000
v 0.500000 -0.500000 -0.500000

vt 0.000000 0.000000
vt 1.000000 0.000000
vt 0.000000 1.000000
vt 1.000000 1.000000

vn 0.000000 0.000000 1.000000
vn 0.000000 1.000000 0.000000
vn 0.000000 0.000000 -1.000000
vn 0.000000 -1.000000 0.000000
vn 1.000000 0.000000 0.000000
vn -1.000000 0.000000 0.000000

s 1
f 1/1/1 2/2/1 3/3/1
f 3/3/1 2/2/1 4/4/1
s 2
f 3/1/2 4/2/2 5/3/2
f 5/3/2 4/2/2 6/4/2
s 3
f 5/4/3 6/3/3 7/2/3
f 7/2/3 6/3/3 8/1/3
s 4
f 7/1/4 8/2/4 1/3/4
f 1/3/4 8/2/4 2/4/4
s 5
f 2/1/5 8/2/5 4/3/5
f 4/3/5 8/2/5 6/4/5
s 6
f 7/1/6 1/2/6 5/3/6
f 5/3/6 1/2/6 3/4/6

(It's a simple cube)

rohan-sawhney commented 6 years ago

Closed surfaces (such as a cube) must be cut before flattening them - the BFF class expects a surface with boundary as input. Take a look at the Cutter & Viewer classes to cut through closed surfaces.

lukkio88 commented 6 years ago

I have a larger surface, which isn't closed. I still have the same problem.

lukkio88 commented 6 years ago

Ok, I've sorted out for now (basically at some points some of my wrappers are used hence it crashed, of course).

Out of curiosity what exactly are the boundary conditions you suggested? i.e. what do they represent?

keenancrane commented 6 years ago

They represent "no scaling" along the boundary: the length of each piece of the flattened boundary curve will be the same as the original boundary curve. This condition in turn implies that the scale distortion over the interior domain is as small as it possibly could be. So, it provides a good default choice for flattening: zero angle distortion, and minimal area distortion.