-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
STL file support #1
Comments
Hi Stefano,
thanks for the heads up. I originally implemented the binding for a now-old
version of CGAL. It is probably time to update it. It already gives a lot
of warnings about deprecation. It is just hard to find the time.
I found this link
https://stackoverflow.com/questions/30329398/what-mesh-file-types-are-supported-for-input-by-the-c-library-cgal
which will probably enable reading of STL files. I normally also receive
data as STL and then have to convert it to OFF with meshconv and MeshLab.
Vladimir
2017-11-15 18:06 GMT+01:00 Stefano Zaghi <notifications@github.com>:
… Dear Vladimir,
I am using your nice binding with great satisfaction, it is really a
helpful code.
I would like to deal directly with a STL file input (instead of OFF), do
you think it is possible?
Cheers.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#1>, or mute the
thread
<https://github.com/notifications/unsubscribe-auth/AAskEStIt5ocJWMyMUwWtdArsCSxA-5zks5s2xkngaJpZM4QfQPR>
.
|
Hi Vladimir, thank you very much for your help, it is really appreciated.
I see the warning, but I am not up to the task to write c++ code, I cannot help, my bad. I also using meshconv, but dealing directly with STL is more convenient. Anyhow, thank you again for sharing this helpful code! Cheers. |
I will keep this open, I think it is worth doing something in the relatively near future. |
If I can help in some way, please let me know. Cheers. |
Dear Vladimir, at the end I decided to move toward a fully Fortran library for the computation of point-surface(triangulated)-distance. I wrote a library (still in beta) that does IO directly STL files and does (signed or not) distance computation by means of also AABB acceleration (point-in-polyhedron test still does not exploit AABB tree hierarchy, but it is a simple step that I hope to add next week). Preliminary tests show very good accuracy and computation speed, but I have to clean the code and to make more tests and analysis. The library is here (develop branch) https://github.com/szaghi/FOSSIL/tree/develop I hope it could be of some help also for you. |
Thank you, that sounds really promising! Messing with the CGAL traits and templates is really hard, I tried to do something, but it is just very difficult for me. But, to be fair, I couldn't find the right Demo example to begin with, and it is right here in the Stack Overflow answer you linked! Anyway, I think a smaller Fortran code might be much better. I wonder whether the class of accepted STL files will be similar to CGAL or wider as I often have problems loading a file even when Meshlab told me it is orientable. |
Hi Vladimir, currently, the library accepts (blindly) any STL, it is almost agnostic, it assumes the input to be really a "cloud of triangles" as an STL should be. The distance (square or square root) computation should work as it, but if you ask for signed distance the quality of STL does matter. In particular, it is important that the facets normals are consistent (or similarly that the three points of facet are well numbered, the normals are recomputed by the library by the three points-facet) and/or the whole polyhedra has not holes (namely the surface is watertight), but no checks is done before assigning the distance sign. I use Salome to generate STL from CAD (iges generally), thus making normals consistent or generating watertight STL is relatively simple. If I will have the time, I'll try to understand the algorithm of admesh for filling holes and sanitizing normals in order to put them into the library and doing the right checks/actions before trying to compute the sign. I'll public the first stable release soon. Thank you again for your help. Cheers. |
Hi Vladimir, good news: I found the time to add some methods to inspect and sanitize STL. Now the library can "repair" inconsistent normals orientation, reconstruct triangles connectivity and compute volume. Now it is possible to alert for holes and the like and eventually to try to fill them (not yet implemented). I'll add some transformation methods (scale, rotate, mirror...) before the 1.0.0 version, but it is quite usable now. At the end I added most part of the admesh tools combining it with a robust and efficient (signed) distance computation, that was what I need to pre-process my (very) bad input STL files. Cheers. |
That looks terrific!
Now I have to find a way how to easily integrate it into my code. Or how to
easily install the library at any Linux computer with quite old compilers,
old Python and other old programs. Currently I am just stack at installing
FoBiS in my home directory. I think the route might be long.
2018-05-07 17:35 GMT+02:00 Stefano Zaghi <notifications@github.com>:
… Hi Vladimir,
good news: I found the time to add some methods to inspect and sanitize
STL. Now the library can "repair" inconsistent normals orientation,
reconstruct triangles connectivity and compute volume. Now it is possible
to alert for holes and the like and eventually to try to fill them (not yet
implemented). I'll add some transformation methods (scale, rotate,
mirror...) before the 1.0.0 version, but it is quite usable now. At the end
I added most part of the admesh tools combining it with a robust and
efficient (signed) distance computation, that was what I need to
pre-process my (very) bad input STL files.
Cheers.
—
You are receiving this because you were assigned.
Reply to this email directly, view it on GitHub
<#1 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAskEYA6nhma2vr8cV4nys_4EgiYlJsaks5twGncgaJpZM4QfQPR>
.
|
:-) You are too much kind. Indeed, all seems to work smooth, but for example I need to check more accurately the robustness of the connectivity reconstruction algorithm. Nevertheless, I am going to use it in production, thus any weakness will arise soon. As for the installation/use you do not need FoBiS: I can give you a legacy makefile if you like it and a more simple install script not based on git. Let me know if you want to try it. Cheers. |
Hi Vladimir, a new release is out, v1.0.1, it brings two interesting news (I hope):
For now I am quite satisfied by the current features of FOSSIL, but if you have any requests I am happy to try to add them (probably tomorrow I'll add the possibility to trim out facets outside a given bound box, a sort of clip method). Cheers |
Hi Stefano,
I managed o compile the code just by adding all the files to scons and let
it sort out the dependencies. I had to do several fixes for gfortran 5.3.1,
because it requires explicit array shape in sourced allocation. I just used
size(the_source).
I tested it on this model https://www.thingiverse.com/thing:1284 which
wasn't openable using CGAL (after conversion to OFF).
It took a long time to process, but it loaded the model and printed
statistics:
VCG
file name: thing_1284.stl
file format: binary
X extents: [+0.489914215087891E+003, +0.627857482910156E+003]
Y extents: [+0.541161003112793E+002, +0.323471984863281E+003]
Z extents: [+0.276616992950439E+002, +0.137778503417969E+003]
volume: -0.230737701906748E+007
number of facets: +130730
number of facets with 1 edges disconnected: +0
number of facets with 2 edges disconnected: +0
number of facets with 3 edges disconnected: +0
Waht does the negative volume mean?
I will try some decimation to make it smaller and test the speed, but
sometimes I have large files (terrain XYZ maps).
Cheers,
Vlada
2018-05-16 15:45 GMT+02:00 Stefano Zaghi <notifications@github.com>:
… Hi Vladimir,
a new release is out, v1.0.1, it brings two interesting news (I hope):
- a standalone program that does essentially the same job of admesh
except for filling holes;
- the capability to automatically connect facets that are disconnected
but very close (the common scenario when dealing with poor STL inputs).
For now I am quite satisfied by the current features of FOSSIL, but if you
have any requests I am happy to try to add them (probably tomorrow I'll add
the possibility to trim out facets outside a given bound box, a sort of
clip method).
Cheers
—
You are receiving this because you were assigned.
Reply to this email directly, view it on GitHub
<#1 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAskERU8gKh5G4FC3l_Bl2RxzxNZgS_Vks5tzC1ygaJpZM4QfQPR>
.
|
Just as a note, I now used the Quadric Edge Collapse Decimation in Meshlab to reduce the number of facets 10x and the file was loaded very quickly. By several orders of magnitude faster. Vlada |
Hi Vladimir, great test! Efficiency has not been still taken into account, I am focused more on the robustness/correctness, but the next step is to improve IO and manipulation speed. As you know, I am not a very good programmer, your help into optimizing the library could be very helpful. I am using gfortran 7.x, thus 5.3.1 is out of my scope, I cannot help in this regards. Anyhow, I had tried to be standard conforming, thus if the only change you needed was to modify source allocation I can certainly patch my code to "incorporate" your more robust allocation. The negative volume simply indicates that the normal are not "all counter clock oriented/consistent": try to sanitize them and recompute volume call file_stl%sanitize_normals
call file_stl%compute_volume
print*, call file_stl%statistics() Thank you very much for your feedback! |
I will try to do some profiling. The problem is that I tried to open a file
I used for simulations before and it hasn't been loaded yet since yesterday
evening.
This is the backtrace where it seems to be stuck:
#0 fossil_facet_object::are_nearby (tolerance=6.9530912824159187e-310,
b=..., a=...) at /home/lada/f/FOSSIL/src/lib/fossil_facet_object.f90:167
#1 fossil_facet_object::compute_vertices_nearby (self=..., other=...,
tolerance_to_be_identical=1.7881393432617188e-07,
tolerance_to_be_nearby=0.89818725585937498)
at /home/lada/f/FOSSIL/src/lib/fossil_facet_object.f90:144
#2 0x0000000000440666 in fossil_file_stl_object::build_connectivity
(self=...) at /home/lada/f/FOSSIL/src/lib/fossil_file_stl_object.f90:111
#3 0x00000000004407b9 in fossil_file_stl_object::analize (self=...) at
/home/lada/f/FOSSIL/src/lib/fossil_file_stl_object.f90:92
#4 0x000000000043f220 in fossil_file_stl_object::load_from_file (self=...,
file_name=<error reading variable: value requires 475630 bytes, which is
more than max-value-size>,
is_ascii=<error reading variable: Cannot access memory at address 0x0>,
guess_format=.TRUE., disable_analysis=<error reading variable: Cannot
access memory at address 0x0>, _file_name=_file_name@entry=0)
at /home/lada/f/FOSSIL/src/lib/fossil_file_stl_object.f90:432
#5 0x0000000000442abe in MAIN__ () at fossil-test.f90:4
2018-05-17 18:35 GMT+02:00 Stefano Zaghi <notifications@github.com>:
… Hi Vladimir,
great test!
Efficiency has not been still taken into account, I am focused more on the
robustness/correctness, but the next step is to improve IO and manipulation
speed. As you know, I am not a very good programmer, your help into
optimizing the library could be very helpful.
I am using gfortran 7.x, thus 5.3.1 is out of my scope, I cannot help in
this regards. Anyhow, I had tried to be standard conforming, thus if the
only change you needed was to modify source allocation I can certainly
patch my code to "incorporate" your more robust allocation.
The negative volume simply indicates that the normal are not "all counter
clock oriented/consistent": try to sanitize them and recompute volume
call file_stl%sanitize_normalscall file_stl%compute_volumeprint*, call file_stl%statistics()
Thank you very much for your feedback!
—
You are receiving this because you were assigned.
Reply to this email directly, view it on GitHub
<#1 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAskESuqHYltJimMvwZ3-Aia97Yi9XsTks5tzabBgaJpZM4QfQPR>
.
|
Hi Vladimir, this sounds an interesting test that could help me to find a lot of bugs: the nearby search should be quite simple, I guessed that the problem was on connectivity reconstruction, but as often happens I am wrong. Can you share this STL? Or another (maybe reduced/manipulated to be shared) raising the same issue? Thank you again for the feedbacks. |
I returned to the original STL I tried first (from the thingiverse link). I analyzed it using Oracle Studio Analyzer. It has been a very nice tool for many years, extremely under-rated in my opinion. The call to My guess is that it is just called for too many combinations of vertices and that there has to be some heuristic to limit the number of calls for distant pairs. |
Yep, in fact my idea was just to exploit the already present AABB levels to speedup also nearby search. I'll try to do it monday. Oracle Studio Analyzer sounds interesting, thanks! |
I tried the current develop branch and it loaded the file really fast! Just the API has changed somewhat from the README file so I didn't get far yet, but I was able to print the size of the facet array. Is there a reason why the facets are now returned as a separate array in load_from_file? |
Oh no, my bad, I was to slow... Yes, there was a reason for separating file handler from surface one: I need to write the facets contained into each AABB block (that is a member of surface handler) created to speedup distance/connectivity computation, thus in order to avoid code-duplication I used the same file handler to save AABBs STL, just like a surface STL... a little cumbersome, but the code now has less duplication. I hope to push a stable release soon with up-to-date documentation, I am sorry. Anyhow for very big input like yours I suggest to use high refinement levels (>2, maybe 5 or 6 or even more) for AABB structure. I am thinking to insert a method to automatically set a good refinement level basing on the shortest edge length... Thank you very much for your feedback. |
Vladimir, I pushed a new stable release, this should be quite stable (I should not break the compatibility anymore). It should be quite efficient now in loading and analyze big input, anyhow it has also the "clip" feature on loading: if the input is really huge you can load it by "clip" (providing bound box extents) and only the facets falling inside the clip will be loaded (it could be of some help for partioning the workload/tests...). I also added a new "distance" method: Cheers. |
It seems to me that you are confusing explicit interface and interface
block. They are very different.
Explicit interface is when the calling code know how the procedure looks
like and is required for many features. Normally, explicit interface is
provided using a module, sometimes using internal procedures. Only in
limited cases you use interface blocks.
Interface blocks are blocks of code that begin with `interface` and end
with `end interface`. They are useful for many things like generics,
procedure arguments and abstract procedures, but not too often for
providing explicit interface.
Dne po 4. 6. 2018 21:27 uživatel Zvi <notifications@github.com> napsal:
… @szaghi <https://github.com/szaghi>
Hello!
Several procedures are used externally (from other modules and from calls
to the FOSSIL out of a main code). As far as I know, the use of optional
arguments for external procedures requires an explicit interface, otherwise present(optional
variable) will always return .true. - I had this issue several times
before and whenever making an explicit interface was too much of a mess, I
ended up adding another logical (non-optional) variable instead of just
using the optional variable. I think that when it is inside the same
module, there's no problem, but when it's external (i.e. module to module),
the compiler (ifort at least) always assumes that all of the variables are
given.
I have emailed you regarding a specific case in the code, but there are
definitely others
When checking for clipping:
1. The clip check happens twice - one before allocating and twice
after. Instead, maybe create a linked-list of integers type, such that
every time that a facet is inside - add the current index to the list. Once
done reading the file, (if FILO revert the list by replacing the pointers),
and on the second run (after allocating) - you can only check if the index
matches the index on the list head. If it does, save the facet and pop-out
the head, moving to the next in line. You can verify that reading was done
properly if at the end the list has size of 0.
2. The current way you check if "inside" only includes facets which
have all of the vertices inside the bounding box. There are cases where
facets will have only several (but not all) vertices inside or even cases
where all the vertices are outside, but the facets still intersects the
bounding box.
My suggestion is to use the following (I'm using element instead of
facet to make sure that there is no confusion: element = a facet from the
STL surface):
Phase 1: Checking the BOUNDING BOX VERTICES relative to the element plane
Based on the normal of the element, check the signed distance of each bounding-box vertex from the plane of the element.
If any of the distances==0.0 then the element is to be included.
If all 8 bounding-box vertices have positive distance or all 8 have negative distance - discard it.
Phase 2: Checking the ELEMENT VERTICES relative to the bounding-box
For each Bounding-Box facet (6 total), count how many element vertices are "outside"
(based on the face normal, pointing outwards - same algorithm/concept as convex polygon).
Since this is a AABB, it can be simplified to counting vertex.x<bmin.x, vertex.x>bmax.x and repeat for y,z).
If all of these are less than the element vertex number (3 for triangle) - include it.
(I think this can also be directly expanded to work for any convex
bounding polygon and convex element)
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#1 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAskEQiv_apkp11gs_r3yqAnendURvmFks5t5YongaJpZM4QfQPR>
.
|
@LadaF , First off, I figured I should move the comment to the FOSSIL page, I have deleted the comment here as such. Maybe I shouldn't have. As for the issue at hand: But allow me to clarify: I have referred specifically to an interface block in the calling module A which specifies, among other things, the OPTIONAL arguments as well. So that the calling code in module A will know to communicate properly if an optional argument was passed or not to the procedure on module B. If such an interface does not exist - the present(optional argument) in the procedure in module B will always return .true. |
I am sorry, but you got this wrong.
If you use modules, you do NOT need interface blocks to provide explicit
interface. Explicit interface is provided by the modules.
Read Steven Lionel's article
https://software.intel.com/en-us/blogs/2012/01/05/doctor-fortran-gets-explicit-again
it is really informative.
I have written loads of stuff about explicit interfaces on Stack Overflow
myself BTW.
Dne po 4. 6. 2018 22:03 uživatel Zvi <notifications@github.com> napsal:
… @LadaF <https://github.com/LadaF> , First off, I figured I should move
the comment to the FOSSIL page, I have deleted the comment here as such.
Maybe I shouldn't have.
As for the issue at hand:
Perhaps my terminology is incorrect, but I am using Steve Lionel's (Intel)
<https://software.intel.com/en-us/forums/intel-visual-fortran-compiler-for-windows/topic/275071#comment-1548437>
terminology, which is also used on Stackoverflow
<https://stackoverflow.com/questions/3121954/fortran-90-presence-of-optional-arguments>
and others.
But allow me to clarify:
Say that module A has a code calling a procedure with optional arguments
which exists in module B.
I have referred specifically to an interface block in the calling module
which specifies, among other things, the OPTIONAL arguments as well. So
that the calling code in module A will know to communicate properly if an
optional argument was passed or not to the procedure on module B. If such
an interface does not exist - the present(optional argument) in the
procedure in module B will always return .true.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#1 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAskEWcb9StSodnlKQc_C-TNl_lMe95gks5t5ZJygaJpZM4QfQPR>
.
|
I definitely agree you know what you are talking about - your reputation goes way ahead of you. |
Yes, it does. You wouldn't be able to call them otherwise. Module
procedures cannot be called as external procedures (unless you do some
dirty tricks with name mangling).
2018-06-04 23:17 GMT+02:00 Zvi <notifications@github.com>:
… I definitely agree you know what you are talking about - your reputation
goes way ahead of you.
However, is this correct also when using only parts of the module?
If use fossil_aabb_tree_object, only : aabb_tree_object is used, does
that include the interface for all the public methods in 'module
fossil_aabb_tree_object' under contains?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#1 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAskEXsD5GHU8nlLKkJtED7tiqSfR5cXks5t5aPPgaJpZM4QfQPR>
.
|
Alright, so it's not the "optional" issue.
And the output was:
I tried with ascii and binary formats, also tried to redo this "manually". |
@ZviHantsis your last example is not useful: please provide a full executable test in order I can try to fix the possible bug. It is not my Anyhow, I do not understand the Cheers |
I think it will be better to continue in the issue opened at the FOSSIL
page.
2018-06-05 10:18 GMT+02:00 Stefano Zaghi <notifications@github.com>:
… @ZviHantsis <https://github.com/ZviHantsis> your last example is not
useful: please provide a full executable test in order I can try to fix the
possible bug. It is not my fossil_test_distance, but it looks like to be
extracted from it.
Anyhow, I do not understand the opitional gate...
Cheers
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#1 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAskEY_mCUA6w1GRribYarAI0NpHbhX5ks5t5j7SgaJpZM4QfQPR>
.
|
Returning to the issue in the title, here is some explanation why dealing with STL files is complicated and hence the need for complicated code in CGAL demos, such as https://github.com/CGAL/cgal/blob/master/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp and why FOSSIL needs subroutines such as |
Dear Vladimir,
I am using your nice binding with great satisfaction, it is really a helpful code.
I would like to deal directly with a STL file input (instead of OFF), do you think it is possible?
Cheers.
The text was updated successfully, but these errors were encountered: