Giter VIP home page Giter VIP logo

meshinspector / meshlib Goto Github PK

View Code? Open in Web Editor NEW
423.0 15.0 42.0 34.35 MB

Mesh processing library

Home Page: https://meshinspector.com

License: Other

CMake 0.58% CSS 0.05% Python 1.84% Shell 0.36% Batchfile 0.01% C++ 89.40% C 6.33% JavaScript 0.54% HTML 0.02% Rich Text Format 0.01% Cuda 0.77% Dockerfile 0.01% Objective-C++ 0.10% Ruby 0.01%
3d mesh voxel distance-map cpp geometry library mesh-analysis mesh-processing mesh-decimation

meshlib's Introduction

MeshInspector releases

MeshInspector is an application for geometry processing based on MeshLib. Find more on our website. Download MeshInspector (Windows/Linux/Mac).

MeshInspector online web-browser version (simple email sign-in is required)

Submit an issue

image

Technology

  • OpenGL v4 by default, v3 for a compatibility

Performance

  • Fast drawing up to 20+M triangles,
  • Hardware-accelerated object picker (finding triangle or point under the cursor).

Viewport camera modes

  • Perspective and Orthographic,
  • Renderable objects
    • Cloud points,
    • Meshes,
    • Lines,
    • Voxels
    • DistanceMaps

Color and textures

  • Vertices color map,
  • Triangles color map,
  • Static textures.

Order independed transparency

Perfect and fast visualization of many transparent objects with complex geometry using OpenGL 4: image

Convenient for mesh algorithms debugging, showing mesh edges, boundaries

Computed-tomography reconstruction

An ability to reconstruct voxel object from a set of projection images (radiographs) and known cone-beam CT scanner geometry parameters. Nvidia GPU is utilized via CUDA technology for the best reconstruction performance.

meshlib's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

meshlib's Issues

offset on a very simple mesh crashes my Ubuntu VM

I have this simple stl file of 4 triangles, very simple (the attached file is an stl file renamed as txt).
Running this python code, the memory increase till the crash of the VM:

mesh= mrmeshpy.loadMesh(fn)

params = mrmeshpy.OffsetParameters()
params.voxelSize = 0.0
params.type = mrmeshpy.OffsetParametersType.Shell

shell = mrmeshpy.offsetMesh(mesh, -2, params)

Can you check, please?

Thanks
Fabio

Meshlib 2.1.6
aaaaaaa_TH4.2000.txt

Inspect > Distance Compare map between two meshes in python?

Hi,
Great work! But I feel the documentation is lagging behind the efforts. I wanted to know if it is possible to use the "Inspect > Distance Compare" functionality of Mesh Inspector, but completely in python? For example, I could compute the Signed Distance between the two meshes using:

  import meshlib.mrmeshpy as mr

  mesh1 = mr.loadMesh("Cube.stl")
  mesh2 = mr.loadMesh("Torus.stl"))
  z = mr.findSignedDistance(mesh1, mesh2)
  print(z.signedDist)

Which gives the same output as "Inspect > Signed Distance" in Mesh Inspector.
How to have the Distance Compare map in python?

Thank you.

Part of the feature edge

I found that there is a global search for feature edges in the software.But if I want to find a local segment of a line.What should I do better?
For example, the cyan edge has two tangent lines at both ends.
27f4d1b5896df1b3fc39f1d30a05b49
How should I find out the local characteristic edge out

Two contour fills

I see that the software currently only supports one contour for filling.
image
I can't choose two contours
If I want to fill between two contours, how should I do it best?I need to fill between two contours

Mesh Traversal

I'm trying to gain a better understanding of how to navigate the mesh topology. Could you please point me in the right direction when it comes to the following operations?

  1. Face/Edge/Vertex Selection
    Given a ray, how can I select the intersecting mesh element? The function below returns a MeshTriPoint, is there a way to retrieve the corresponding Face, Edge or Vertex?

    MRMESH_API std::optional<MeshIntersectionResult> rayMeshIntersect( const MeshPart& meshPart, const Line3f& line,
    float rayStart = 0.0f, float rayEnd = FLT_MAX, const IntersectionPrecomputes<float>* prec = nullptr, bool closestIntersect = true );

  2. Internal Face Selection
    Given a closed edge loop (cyan), select all internal faces (yellow):
    image
    image

  3. Hole & Boundary Selection
    Given a single edge (cyan), select the entire edge loop forming the hole boundary (yellow). Same applies to external boundaries:
    image
    image

  4. Expanding/Shrinking Selection
    Given an arbitrary amount of selected faces expand or shrink the selection to include the neighboring faces:
    image
    image

MeshInspector app cannot run on iphone 8 (ios 14.5)

Hello,

The meshlib demo web application(https://app.meshinspector.com/RMISingle/) cannot run on iphone8 (ios 14.5). I tested it on real machine and the simulator, both failed. Besides, it runs normally with higher ios version.

I compiled the web application(single-thread) from source code, but result in same problem.

It will be much helpful if the single-thread (and maybe no simd?) meshlib can work on much more mobile deivces. Do you have any ideas? Thanks.

Whether meshlib supports running on the browser through wasm

I'm interested in meshlib, which has a lot of features I need, and I want to use it in the browser to improve the efficiency of 3D operations. Does meshlib support converting to wasm to run in a browser? If there is a feasible plan can you provide some ideas?

mrmeshpy.boolean intersection returns not(intersection)

I am trying to calculate the intersection between two meshes by calling

import meshlib.mrmeshpy as mr
mesh_a = ...
mesh_b = ...
diff = mr.boolean(mesh_a, mesh_b, mr.BooleanOperation.Intersection)

However, instead of returning the intersection of the two meshes, I end up getting the not(intersection) of the two meshes. By not(intersection) i mean parts of mesh_a that don't lie inside mesh_b.

For example, given mesh_a:

with mesh_b on top:

i get the intersection as:

Any clue on what might be happpening?

Find the half edge between two points

If I input two coordinate points of the surface model, I want to find the half of the geodesic distance between the two points?
d7fb11e287f30604bf17f53a314b08d
How should I split the mesh and figure out the proper half edge?
code**************************
auto cylinder = MR::MeshLoad::fromAnyStl("D:/code/meshlib221/chamfer/model/cylinder.stl");
MR::vector3f pointA;
MR::vector3f pointB;
code****************************
Do I need to split the mesh one by one?
std::vectorMR::EdgeId MeshContours;

Debugging issues

When I use library files for debugging,Can I have a link to the source code?
4e848cd15ac4976ec4fc4c5084adfbc
Can I debug directly into the cpp file?
d2be4c2e4896502ac4cd1b67a9b6e9c
I want to see other data during the debugging process
f4423f2e59e1a1523b48a88b81b4190

Python, 'region' attribute error when subdivide mesh: 'meshlib.mrmeshpy.SubdivideSettings' object has no attribute 'region'

Hello everyone,

There is an attribute error when i want to subdivide a region of mesh and set the 'region' attribute. Below is my test code, its the test code from MeshLib/test_python/test_subdivider.py but with 'region' attribute modifed. And I have not figure out how to set the 'region' attribute value rightly, so just set as None to show the error.

from helper import *
import pytest


def test_subdivider():
    torus = mrmesh.makeTorus(2, 1, 10, 10, None)
    countInit = torus.topology.getValidFaces().count()

    settings = mrmesh.SubdivideSettings()
    settings.maxEdgeLen = 0.3
    settings.maxEdgeSplits = 5
    settings.maxDeviationAfterFlip = 0.2

    # Error: 'meshlib.mrmeshpy.SubdivideSettings' object has no attribute 'region'
    settings.region = None

    mrmesh.subdivideMesh(torus, settings)

    assert (torus.topology.getValidFaces().count() > countInit)

The error says,

'meshlib.mrmeshpy.SubdivideSettings' object has no attribute 'region'

Besides, I found the 'region' attribute is indeed binded and there also exists 'region' attribute in debug window, but i still cannot set this attribute and the error occured.

the debug window picture,
Screenshot from 2022-12-08 12-34-14

Finally, thank you for this amazing library!

Find boundary intersections

Hello,If I know two points on the model surface, can I use those two points to find the intersection with the model boundary?
a1e793910649c1d212d69d2266fb6bf


We can use the following as input: mesh, upper surface, two point coordinates.
Desired result: Find the intersection with the left boundary

python filling hole(and stitching two holes) with same result as MeshInspector

Hello,

I'm testing stitching_two_holes function using python code which is similar to here, but got bad result in some cases. For example, (1) very narrow triangle directly linking the two hole border even after subdivision. (2) or the result mesh is exploded. I modified some filing hole configurations but cannot solve those problems. Besides, because we cannot modify the mesh's existing region when filing holes, I need to set SubdivideSettings.subdivideBorder=False(but this cannot avoid problems).

I tested the meshInspector's stitching_two_holes function, and it works correctly on my test meshes. I wonder if you can provide some sample code which can get same result as MeshInspector. With that, we can compare hole filling result with meshinspector directly when we encountered bad result. And it will be much convenient to report problems to you.

Thanks.

Geodesic Question

Hello,Is it not possible to use the output results directly?
When I use the geodesic algorithm directly, I find that the points in the middle cannot be printed
code**********
auto model = MR::MeshLoad::fromAnyStl("D:/code/meshlib223/ChamferAllEdges/model/Subtraction.stl");
auto firstTriPointTest = MR::MeshTriPoint::MeshTriPoint(model->topology, model->topology.org(MR::EdgeId(211)));
auto secondTriPointTest = MR::MeshTriPoint::MeshTriPoint(model->topology, model->topology.org(MR::EdgeId(111)));
MR::GeodesicPathApprox atype = MR::GeodesicPathApprox::DijkstraBiDir;
auto geoDesicPath = MR::computeGeodesicPathApprox(model,firstTriPointTest,secondTriPointTest,atype);
for (auto geoDesic : geoDesicPath)
{
std::cout << model->edgePoint(geoDesic).x << " " << model->edgePoint(geoDesic).y << " " << model->edgePoint(geoDesic).z << std::endl;;
}
code
************

Remeshing

Encouraged by the performance of mesh booleans and polyline-mesh intersections, I took the remeshing function for a spin:

MRMESH_API bool remesh( Mesh& mesh, const RemeshSettings & settings );

Below is a comparison with Geometry Central and cinolib

2023-06-17.19-49-08.mp4

In the upper left corner you see the timings and MeshLib is a clear winner here, especially with higher amount of remeshing iterations.
There are, however, a few issues I can see with the results:

  1. The algorithm doesn't seem to change the mesh when target edge length is set to exceed the longest edge (in this case >4.5)
  2. GC and cinolib refine the mesh with each remeshing iteration. MeshLib seems to only work once.
  3. MeshLib is quite inconsistent - notice how some portions of the mesh are mor refined than the others:
    image

For reference, here is how I call this function:

	RemeshSettings settings = RemeshSettings();
	settings.targetEdgeLen = targetLength;
	settings.packMesh = true;
	settings.maxAngleChangeAfterFlip = 30 * PI_F / 180.0f;

	for (int i = 0; i < iterations; i++ )
		remesh( *mesh, settings );

Cut off part feature of the mesh model

Hello,If I use a plane to cut off a model, can I cut off some mesh features?For example, I want to cut off the A feature of the mesh model, but I don't want to cut off the B feature of the mesh model.
8026feec4a602a13d8f0fd999024439
Is there any better way to solve this problem?

Curved cylinder

Is there a algorithm that can convert 3d polyline to a triangle mesh as shown above?
image
image

Cut meshes with polylines

First of all - thanks for your great work on this library! It's really coming together nicely!

Since there is no dedicated Discussion section, I'd like to ask here whether it's possible to cut meshes with polylines. Example below:

image

Please note how new vertices and edges are introduced to the mesh and it is pulled towards the user provided polyline.
Any suggestions how this could be achieved in MeshLib?

mesh denoising that can keep sharp features

Do you have plans to write mesh denoising algorithms that can keep sharp features of flat regions and smooth regions.
image
see the flat regions and the hole in the above image

MeshLib using

Hi,are there some examples can use to learn how to use the api?

Building on Windows

I'm trying to build MeshLib on Windows 10 following this guide.

It fails at the following line:
../MeshLib/thirdparty/install.bat

set VCPKG_DEFAULT_TRIPLET=x64-windows-meshlib

error: Invalid triplet: x64-windows-meshlib
Available architecture triplets:
vcpkg built-in triplets:
  arm-uwp
  arm64-windows
  x64-linux
  x64-osx
  x64-uwp
  x64-windows-static
  x64-windows
  x86-windows
VCPKG community triplets:
  arm-android
  arm-ios
  arm-linux
  arm-mingw-dynamic
  arm-mingw-static
  arm-neon-android
  arm-windows-static
  arm-windows
  arm64-android
  arm64-ios
  arm64-linux
  arm64-mingw-dynamic
  arm64-mingw-static
  arm64-osx-dynamic
  arm64-osx
  arm64-uwp
  arm64-windows-static-md
  arm64-windows-static
  armv6-android
  ppc64le-linux
  s390x-linux
  wasm32-emscripten
  x64-android
  x64-freebsd
  x64-ios
  x64-linux-dynamic
  x64-linux-release
  x64-mingw-dynamic
  x64-mingw-static
  x64-openbsd
  x64-osx-dynamic
  x64-osx-release
  x64-windows-release
  x64-windows-static-md
  x86-android
  x86-freebsd
  x86-ios
  x86-mingw-dynamic
  x86-mingw-static
  x86-uwp
  x86-windows-static-md
  x86-windows-static
  x86-windows-v120

I replaced the triplet with x64-windows-release and it proceeded further but fails at installing boost:

error: building boost-system:x64-windows-release failed with: BUILD_FAILED
error: Please ensure you're using the latest port files with `git pull` and `vcpkg update`.
Then check for known issues at:
    https://github.com/microsoft/vcpkg/issues?q=is%3Aissue+is%3Aopen+in%3Atitle+boost-system
You can submit a new issue at:
    https://github.com/microsoft/vcpkg/issues/new?template=report-package-build-failure.md&title=[boost-system]+Build+error
Include '[boost-system] Build error' in your bug report title, the following version information in your bug description, and attach any relevant failure logs from above.
    vcpkg-tool version: 2022-11-10-5fdee72bc1fceca198fb1ab7589837206a8b81ba
    vcpkg-scripts version: 6f7ffeb18 2022-11-11 (7 months ago)

Is this a known issue?

Add Box3f functions to python

Please, add functions to python - include(Vector3f ), include( const Box & b ), Box & intersect( const Box & b ), contains() , volume()

Inconsistency issue after reading mesh with fromAnySupportedFormat function.

Thank you for providing such an excellent library. However, I have encountered the following issue while using it. As indicated in the comments in the main function, I provided verts and faces to generate the mesh and saved the mesh locally. However, upon reloading the mesh, I noticed that the lengths of the read verts and faces no longer match the original ones. What could be the reason for this?

#include <iostream>
#include <vector>
#include "MRMesh/MRMesh.h"
#include "MRMesh/MRMeshLoad.h"
#include "MRMesh/MRMeshSave.h"
#include "MRMesh/MRPointCloud.h"
#include "MRMesh/MRMeshBuilder.h"


template <typename T>
std::vector<std::array<T, 3>> array1dTo2d(const T* data, const int dataLength) {
    std::vector<std::array<T, 3>> ret;
    for (int i = 0; i < dataLength; i += 3) {
        std::array<T, 3> vs{data[i], data[i + 1], data[i + 2]};
        ret.push_back(vs);
    }
    return ret;
}


void printVerts(const MR::Mesh& mesh)
{
    int numVerts = mesh.topology.lastValidVert() + 1;
    std::vector<float> datas;
    datas.reserve(numVerts * 3);

    for (int i=0; i< numVerts; i++)
        for (int j=0; j<3; j++)
            datas.push_back(mesh.points.vec_[i][j]);

    for (const float& value : datas) {
        std::cout << value << " ";
    }
    std::cout << std::endl;
}

void printFaces(const MR::Mesh& mesh)
{
    const auto& validFaces = mesh.topology.getValidFaces();
    int numFaces = mesh.topology.lastValidFace() + 1;
    std::vector<int> datas;
    datas.reserve(numFaces * 3);

    for ( int i = 0; i < numFaces; ++i )
    {
        MR::FaceId f = MR::FaceId( i );
        if ( validFaces.test( f ) )
        {
            MR::VertId v[3];
            mesh.topology.getTriVerts( f, v );
            for ( int vi = 0; vi < 3; ++vi )
                datas.push_back(v[vi]);
        }
        else
        {
            for ( int vi = 0; vi < 3; ++vi )
                datas.push_back(0);
        }
    }
    for (const int& value : datas) {
        std::cout << value << " ";
    }
    std::cout << std::endl;
}


MR::Mesh transToMesh(const float* verts1d, const int verts1dLength, const int* faces1d, const int faces1dLength)
{
    std::vector<std::array<float, 3>> verts2d = array1dTo2d(verts1d, verts1dLength);
    std::vector<std::array<int, 3>> faces2d = array1dTo2d(faces1d, faces1dLength);

    MR::Triangulation t;
    MR::Mesh result;
    t.reserve(faces2d.size());

    for (const std::array<int, 3>& data : faces2d) {
        t.push_back( {
            MR::VertId( int( data[0] ) ),
            MR::VertId( int( data[1] ) ),
            MR::VertId( int( data[2] ) )
            } );
    }

    result.topology = MR::MeshBuilder::fromTriangles( t );
    result.points.resize(verts2d.size());
    for (int i=0; i<faces2d.size(); i++){
        result.points[MR::VertId( i )] = MR::Vector3f(
                float( faces2d[i][0] ),
                float( faces2d[i][1] ),
                float( faces2d[i][2] ) );
    }
    return result;
}

int main() {
    float verts[] = {0.0, 1.0, 2.0, 2.0, 3.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
    int faces[] = {0, 1, 2, 2, 3, 0};

    MR::Mesh mesh = transToMesh(verts, 12, faces, 6);
    // In the generated mesh using the provided verts and faces, 
    // the read verts and faces match the given ones.
    printVerts(mesh);   //    The output print is as follows:  0 1 2 2 3 0 0 0 0 0 0 0
    printFaces(mesh);   //   The output print is as follows:  0 1 2 2 3 0
    MR::MeshSave::toAnySupportedFormat( mesh, "output.stl" );

    MR::Mesh outputMesh = MR::MeshLoad::fromAnySupportedFormat("output.stl").value();
    // When I save the previous mesh to the local storage and then reload it, 
    // the read verts and faces do not match the provided ones.
    printVerts(outputMesh);   //  The output print is as follows:  0 1 2 2 3 0 0 0 0
    printFaces(outputMesh);   //  The output print is as follows:  0 1 2

    return 0;
}

How to split mesh with a new point?

Hi, thanks to such a powerful library for 3d process.

Could anyone please help me with an easy case here: How to split mesh with a new point?

For example:
CU%97 (GH(@W6`KBRCZCJHJ

I have read all documents from meshlib, but examples useful for my case cannot be found.
Because I am familiar with python but not with C++, I have difficults to understand all the function details from documents.

Thank you very much if anyone can help!

Unstable Boolean Operations

Hey MeshLib Team,

I've been experimenting with various boolean operations and have encountered some inconsistencies with specific kinds of geometry.

Note how this configuration works:
image

But moving the cylinder to the sides results in an invalid mesh:
image
image

Code is super simple:

BooleanResult res = boolean( *meshA, *meshB, BooleanOperation::DifferenceAB );

And here is a preview of the results in a debug session where it's clear that the above function returns an empty mesh:
image

I'm attaching the geometry in a position which doesn't work on my machine:
Boolean.zip

[EDIT] I'm running the master branch with this snapshot:
image

Fill part of the face

If I have a contour surface,I want to fill one part first and then fill another part. I can split contours into two parts.
eec7b0282434c21510b989d4fcef18d
How should I avoid the influence of patch modification after the first filling?

PointCloud sampling

Hello!

I'm dealing with relatively large point-clouds (5-10M points). For my workflow, I need to sample these with a regular grid of approx. 10 000 sample points and find the id of the closest points from the point cloud to each sample point.

In Rhino 5M points and 10 000 samples takes approx. 20s to compute. Do you think MeshLib could do this faster?

I need this for a wind simulation study. Here is an example for a much smaller point cloud which runs in real-time:
image

https://www.youtube.com/watch?v=l33cxovz_3I

Mesh Segmentation

Hey,

I am trying to segment a mesh using MeshLib, I am not able to find the related source library or example. Do you an example for it?
Assuming this input mesh:

import meshlib.mrmeshpy as mrmeshpy
 
try:
    mesh = mrmeshpy.loadMesh(mrmeshpy.Path("mesh.stl"))
except ValueError as e:
    print(e)

Thanks!

Best,
Ahmad

python decimation

When I use decimation the mesh is torn to pieces. How to get rid of it?

import meshlib

name = meshlib.mrmeshpy.Path('jaw.stm')
mesh = meshlib.mrmeshpy.loadMesh(name)
outFaces = meshlib.mrmeshnumpy.getNumpyFaces(mesh.topology)
print(outFaces.shape[0])    # 249319

settings = meshlib.mrmeshpy.DecimateSettings()
settings.maxDeletedFaces = outFaces.shape[0] - 10000
settings.packMesh = True
dec_mesh = meshlib.mrmeshpy.decimateMesh(mesh, settings)

jaw

MROffset to keep sharp features

you use openvdb to do mesh offset. It is good. but the origin openvdb code can not preserve sharp features.
Do you have plans to optimize the code to keep sharp features?

pip install failing

when I try pip install meshlib I get this error

ERROR: Could not find a version that satisfies the requirement meshlib (from versions: none)
ERROR: No matching distribution found for meshlib

I've tried on a variety of different python versions on mac and linux and the error persists.

Find the index of the triangle face

Hello,Is it possible to add index information of triangular faces to this software?When I use this software, I want to quickly find the index value or coordinates of a certain vertex, or the index value of a certain patch through the visual interface.

nearly overlaping triangles split

If the mesh have overlapping triangles ,it is easy to resolve this problems I guess, just split triangles.But if the mesh has many nearly overlapping triangles,(this triangles In theory, are not coplanar due to floating-point error),
I used a lot of free softwares, like meshlab meshmixer etc,none of them have this function, I think models with such flaws are common
,Do you have plan to solve this problem?

Interactive Contour Labels

This one is a long shot and not directly related to MeshLib so please bear with me while I explain. In my application, I rely on a GLSL shader to draw contour lines interactively. The majority of the logic takes place in the Geometry Shader, which essentially implements this algorithm.

It works very fast even for complex meshes and I'm happily sharing the code below if you wanted to incorporate it into the MeshInspector.

2023-07-18.16-17-50.mp4

Things slow down, however, when I start displaying labels. The GLSL shader, is only aware of one primitive (triangle) at a time and generates unconnected line segments. I couldn't figure out a way of joining these segments on the GPU, hence I copy them over to the CPU and sort them there. It gets me the results I want, but leads to noticeable slow downs with more complex meshes.

Do you have any suggestions on how to approach it in a more efficient way?

The GLSL shader code:

//vertexShader 
#version 330
layout(location = 0) in vec3 _meshVertex;
layout(location = 1) in vec3 _meshNormal;

out vec3 _normal;

void main() {
_normal = vec3(_meshNormal * 0.01); // offset contours by a small amount to prevent Z-fighting
gl_Position = vec4(_meshVertex + _normal, 1.0);
}

// geometryShader
#version 330 core
layout (triangles) in;
layout (line_strip, max_vertices = 64) out;

uniform mat4 _worldToClip;
uniform vec4 minorColor;
uniform vec4 majorColor;

uniform float majorInterval;
uniform float interval;
uniform int multiplier = 100; // used for float precision while searching for major contours

in vec3 _normal[];
out vec4 color;
out vec3 _positionT;
out vec3 _normalT;


int countAB;
int countBC;
int countCA;

float interpolate(float start, float end, float t){
    return start + t * (end - start);
}
vec3[100] computeIntersections(vec4 start, vec4 end, inout int counter){

    vec3[100] points;
    counter = 0;
    
    float minValue = min(start.z, end.z);
    float maxValue = max(start.z, end.z);
    float startValue = minValue - mod(minValue, interval);
    float delta = maxValue - minValue;
    float nLevels = floor((maxValue - startValue) / interval);

    for(int i = 0; i <= nLevels; i++){
        float value = startValue + (i * interval);
        if (value < minValue || value > maxValue)
            continue;
        float ratio = (value - minValue) / delta;
        if(start.z > end.z) ratio = 1 - ratio;
        vec3 point = vec3(interpolate(start.x, end.x, ratio), interpolate(start.y, end.y, ratio), value);
        points[counter] = point;
        counter++;
    }
    return points;
}
void drawContours(vec3 normalVector, vec3[100] start, vec3[100] end, vec3[100] mid, int startCount, int endCount, int midCount) {
         _normalT = normalVector;

    for (int i = 0; i < 35; i++) {
         if (i >= startCount) break;
         color = mod(round(start[i].z * multiplier), round(majorInterval * multiplier)) != 0 ? minorColor : majorColor;

         _positionT = vec3(start[i].x, start[i].y, start[i].z);
         gl_Position = _worldToClip * vec4(start[i], 1.0);
         EmitVertex();
         _positionT = vec3(end[i].x, end[i].y, end[i].z);
         gl_Position = _worldToClip * vec4(end[i], 1.0);
         EmitVertex();
         EndPrimitive();
     }

     int count = endCount - startCount;
     for (int i = 0; i < 15; i++) {
         if (i >= count) break;
         color = mod(round(end[endCount - 1 - i].z * multiplier), round(majorInterval * multiplier)) != 0 ? minorColor : majorColor;
         _positionT = vec3(end[endCount - 1 - i].x, end[endCount - 1 - i].y, end[endCount - 1 - i].z);
         gl_Position = _worldToClip * vec4(end[endCount - 1 - i], 1.0);
         EmitVertex();
         _positionT = vec3(mid[midCount - 1 - i].x, mid[midCount - 1 - i].y, mid[midCount - 1 - i].z);
         gl_Position = _worldToClip * vec4(mid[midCount - 1 - i], 1.0);
         EmitVertex();
         EndPrimitive();
     }
}
void main() {    
     int counter1;
     int counter2;
     
     vec3[] AB = computeIntersections(gl_in[0].gl_Position, gl_in[1].gl_Position, countAB);
     vec3[] BC = computeIntersections(gl_in[1].gl_Position, gl_in[2].gl_Position, countBC);
     vec3[] CA = computeIntersections(gl_in[2].gl_Position, gl_in[0].gl_Position, countCA);
     
     // A is the lowest point
     if (gl_in[0].gl_Position.z < gl_in[1].gl_Position.z && gl_in[0].gl_Position.z < gl_in[2].gl_Position.z)
     {
         if(countAB < countCA)
            drawContours(_normal[0], AB, CA, BC, countAB, countCA, countBC);
         else
            drawContours(_normal[0], CA, AB, BC, countCA, countAB, countBC);
     } 
     
     // A is the highest point
     else if (gl_in[0].gl_Position.z > gl_in[1].gl_Position.z && gl_in[0].gl_Position.z > gl_in[2].gl_Position.z)
     {
         if(countAB < countCA)
            drawContours(_normal[0], BC, CA, AB, countBC, countCA, countAB);
         else
            drawContours(_normal[0], BC, AB, CA, countBC, countAB, countCA);
     } 
     
     // B lowest & C highest
     else if (gl_in[2].gl_Position.z > gl_in[0].gl_Position.z && gl_in[0].gl_Position.z > gl_in[1].gl_Position.z)
     {
        drawContours(_normal[0], AB, BC, CA, countAB, countBC, countCA);
     }
     // C lowest & B highest
     else
     {
         drawContours(_normal[0], CA, BC, AB, countCA, countBC, countAB);
     }

} 

//fragmentShader
#version 330 core
out vec4 FragColor;
in vec4 color;

void main()
{
  FragColor = color;
}  

The c# code taking an array of float containing vertex coordinates and normal vectors of respective start & end points of each line segment. Here is the layout, where V1 is a vertex, and N1 its corresponding normal vector.

contourPoints = [V1x, V1y, V1z, N1x, N1y, N1z, V2x, V2y, ... ];
        public void UpdateContourLabels()
        {
            var labels = new Dictionary<double, (List<Point3d>, List<Vector3d>)>();

            if (WorkingMesh == null) return;

            int correctForQuadFaces = WorkingMesh.Faces.QuadCount > 10 ? 2 : 1;
            int count = 0;
            if (generatedPointsCount != null)
                count = (int)generatedPointsCount[0] * 6 * correctForQuadFaces;

            for (int i = 0; i < count; i += 6) // Stride is 6 due to two vec3 coming from the geometry shader
            {
                Point3d p = new Point3d
                {
                    X = contourPoints[i],
                    Y = contourPoints[i + 1],
                    Z = Math.Round(contourPoints[i + 2], 2)
                };

                if (!labels.ContainsKey(p.Z))
                {
                    var v = new Vector3d
                    {
                        X = contourPoints[i + 3],
                        Y = contourPoints[i + 4],
                        Z = contourPoints[i + 5]
                    };

                    labels.Add(p.Z, (new List<Point3d> { p }, new List<Vector3d> { v }));
                }
                else
                {
                    bool isClose = false;
                    foreach (var point in labels[p.Z].Item1)
                    {
                        if (point.DistanceToSquared(p) < TerrainData.ContourLabelSpacing.CurrentValue)
                        {
                            isClose = true;
                            break;
                        }
                    }
                    if (!isClose)
                    {
                        var v = new Vector3d
                        {
                            X = contourPoints[i + 3],
                            Y = contourPoints[i + 4],
                            Z = contourPoints[i + 5]
                        };

                        labels[p.Z].Item1.Add(p);
                        labels[p.Z].Item2.Add(v);
                    }
                }
            }
            ContourLabels = labels;
        }

Find the coordinates of a vertex

Hello,Does it currently support finding coordinates by point index value?I found that the point coordinates are found through the half-edge structure.
code*******
MR::Vector3f orgpoint = cylinder->orgPnt(edge);


If I have a vertex id, can I directly retrieve its coordinates?
For example:MR::VertId Id;Can I find it directly through this id?
Thanks a lot

CutMesh with world contour and extracting cuted parts

If I input ordered points(The points are not in the same plane), first I want to project the points onto the surface of the model, secondly cut the grid model through the connection between points, and finally I want to fill the cut surface with a new surface.
1.I need to intercept this contour line on the model
2.I need to cutmesh by this contour(The contour points are not in the same plane)

Support >1 textures

It would be nice to support >1 textures per object.

The max number of textures could be an initialization param of TPViewer (even better if it could be changed at runtime). Making the parameter a #define would be slighty unconvenient.

Each vertex would have N different texture coords, one per texture. Textures would be mixed according to their alpha channel.

Volumetric Difference between meshes

I'm trying to compare two meshes and compute the volume difference between them. Here is a simple illustration. The cyan mesh (A) is sometimes higher, sometimes lower and sometimes at the same elevation as the magenta mesh (B). Sometimes there is no overlap at all:
image

Cross-sectional view to better illustrate the relationship between these two objects:
image

I'd like to calculate the difference between them and split it into cut (A is below B), and fill (A is above B). The results would be returned both as numerical values and as a heatmap on a resulting mesh. Here is an example from Wikipedia
image

My approach would be to:

  1. Retrieve a bounding box of both meshes
  2. Populate it with a regular grid of points
  3. Shoot rays from each of the points
  4. Calculate the distance between hit points and save the results
  5. Construct a mesh from the grid of points and visualize the results using vertex colors for each of the points

It's relatively simple to implement but the results would be heavily dependent on the resolution of the point grid and it would be hard to trace the exact isolines where meshes transition from cut to fill. Furthermore, I'd like the result to be a series of closed solid meshes as opposed to an open surface mesh.

image

Do you have better ideas on how to approach this?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.