<div dir="ltr">Hi Paul,<div><br></div><div>I may have misunderstood but could you not just project each triangle in the stl mesh onto the frontal plane (using vtkPlane::ProjectPoint() ), then sum the projected areas?</div>
<div><br></div><div>You may have to prune the mesh first of triangles not &quot;facing&quot; the plane... you could use vtkVectorDot to do this. You&#39;ll also have to deal with occluded triangles (if you have them)</div>
<div><br></div><div>hth,</div><div><br></div><div>Goodwin<br><br><div class="gmail_quote">On Wed, Oct 24, 2012 at 2:18 PM, Paul McIntosh <span dir="ltr">&lt;<a href="mailto:paul.mcintosh@internetscooter.com" target="_blank">paul.mcintosh@internetscooter.com</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi All,<br>
<br>
I have been working on a utility for calculating frontal area of an STL mesh<br>
for CFD. I thought I had it cracked my scanning a line through the mesh at<br>
evenly spaced distances and then counting the number of hits (based on the<br>
OBBTree example). However on closer inspection the areas I was getting were<br>
always larger than they should be, with reason being the OBBTree method is<br>
not precise and I was getting double/triple hits at edges. I have included<br>
the code below as it would probably help someone solve some other problem ;)<br>
<br>
Ok - back to the drawing board... the next obvious way of doing this (and<br>
probably quicker) is to render with parallel projection and then count<br>
pixels in the result.<br>
<br>
Is there an easy way to take sceenshot so that pixels are a known size? Any<br>
pointers welcome!<br>
<br>
Cheers,<br>
<br>
Paul<br>
---<br>
<a href="http://www.internetscooter.com" target="_blank">www.internetscooter.com</a><br>
<br>
<br>
<a href="https://github.com/internetscooter/Vespa-Labs/blob/master/VespaCFD/Calculate
FrontalArea/CalculateFrontalArea.cxx" target="_blank">https://github.com/internetscooter/Vespa-Labs/blob/master/VespaCFD/Calculate<br>
FrontalArea/CalculateFrontalArea.cxx</a><br>
<br>
#include &lt;vtkPolyData.h&gt;<br>
#include &lt;vtkTriangle.h&gt;<br>
#include &lt;vtkLineSource.h&gt;<br>
#include &lt;vtkSTLReader.h&gt;<br>
#include &lt;vtkSmartPointer.h&gt;<br>
#include &lt;vtkPolyDataMapper.h&gt;<br>
#include &lt;vtkIdTypeArray.h&gt;<br>
#include &lt;vtkSelectionNode.h&gt;<br>
#include &lt;vtkActor.h&gt;<br>
#include &lt;vtkRenderWindow.h&gt;<br>
#include &lt;vtkRenderer.h&gt;<br>
#include &lt;vtkRenderWindowInteractor.h&gt;<br>
#include &lt;vtkSelection.h&gt;<br>
#include &lt;vtkExtractSelection.h&gt;<br>
#include &lt;vtkDataSetMapper.h&gt;<br>
#include &lt;vtkProperty.h&gt;<br>
#include &lt;vtkObjectFactory.h&gt;<br>
#include &lt;vtkCellArray.h&gt;<br>
#include &lt;vtkCell.h&gt;<br>
#include &lt;vtkInformation.h&gt;<br>
#include &lt;vtkExtractSelectedPolyDataIds.h&gt;<br>
#include &lt;vtkOBBTree.h&gt;<br>
<br>
<br>
// C++<br>
#include &lt;iostream&gt;<br>
using namespace std;<br>
<br>
// just to make things nicer later and save some documentation reading ;)<br>
struct boundingBox {<br>
    double xmin;<br>
    double xmax;<br>
    double ymin;<br>
    double ymax;<br>
    double zmin;<br>
    double zmax;<br>
};<br>
<br>
// this projects a series of lines through a mesh and looks for<br>
intersections to determine frontal area<br>
// lines are projected based on the bounding box and the resolution is<br>
determined by the steps<br>
// For my application I just need to look at frontal area along the X<br>
direction. The follow code could easily be<br>
// adapted to take a direction as a command line option and produce the area<br>
from that .<br>
// So this currently &quot;scans&quot; yMin-&gt;yMax,zMin-&gt;ZMax, with a line from Xmin to<br>
Xmax<br>
// ref:<br>
<a href="http://www.cmake.org/Wiki/VTK/Examples/Cxx/DataStructures/OBBTree_IntersectW" target="_blank">http://www.cmake.org/Wiki/VTK/Examples/Cxx/DataStructures/OBBTree_IntersectW</a><br>
ithLine<br>
int main(int argc, char *argv[])<br>
{<br>
        // check and get the stl input file provided<br>
    if ( argc != 2 )<br>
    {<br>
        cout &lt;&lt; &quot;Required parameters: Filename&quot; &lt;&lt; endl;<br>
        return EXIT_FAILURE;<br>
    }<br>
    std::string inputfile = argv[1];<br>
<br>
    // later this should be a command line option - hard coded for now<br>
    double resolution = 0.005; // step value while scanning - will need to<br>
do some more calculations later if changed<br>
    //char direction = &quot;X&quot;;  // direction of scan<br>
<br>
    // read STL and print out some info<br>
    std::cout &lt;&lt; &quot;Reading: &quot; &lt;&lt; inputfile &lt;&lt; std::endl;<br>
    vtkSmartPointer&lt;vtkSTLReader&gt; stlReader =<br>
vtkSmartPointer&lt;vtkSTLReader&gt;::New();<br>
    stlReader-&gt;SetFileName(inputfile.c_str());<br>
        vtkSmartPointer&lt;vtkPolyData&gt; polydata =<br>
vtkSmartPointer&lt;vtkPolyData&gt;::New();<br>
        polydata = stlReader-&gt;GetOutput();<br>
    polydata-&gt;Update();<br>
    //    Debug info if needed:<br>
    cout &lt;&lt; &quot;Cells: &quot; &lt;&lt; polydata-&gt;GetNumberOfCells() &lt;&lt; endl;<br>
    cout &lt;&lt; &quot;Points: &quot; &lt;&lt; polydata-&gt;GetNumberOfPoints() &lt;&lt; endl;<br>
    cout &lt;&lt; &quot;Polys: &quot; &lt;&lt; polydata-&gt;GetNumberOfPolys() &lt;&lt; endl;<br>
    cout &lt;&lt; &quot;Verts: &quot; &lt;&lt; polydata-&gt;GetNumberOfVerts() &lt;&lt; endl;<br>
    polydata-&gt;Print(cout);<br>
<br>
    // makes sense to only scan in an area the object exists, the bounding<br>
box will tell us this<br>
    double bounds[6];<br>
    boundingBox boxBounds;<br>
    polydata-&gt;GetBounds(bounds);<br>
    boxBounds.xmin = bounds[0] - resolution*5;<br>
    boxBounds.xmax = bounds[1] + resolution*5;<br>
    boxBounds.ymin = bounds[2] - resolution*5;<br>
    boxBounds.ymax = bounds[3] + resolution*5;<br>
    boxBounds.zmin = bounds[4] - resolution*5;<br>
    boxBounds.zmax = bounds[5] + resolution*5;<br>
<br>
    //    Debug info if needed:<br>
    std::cout  &lt;&lt; &quot;xmin: &quot; &lt;&lt; boxBounds.xmin &lt;&lt; &quot; &quot;<br>
               &lt;&lt; &quot;xmax: &quot; &lt;&lt; boxBounds.xmax &lt;&lt; std::endl<br>
               &lt;&lt; &quot;ymin: &quot; &lt;&lt; boxBounds.ymin &lt;&lt; &quot; &quot;<br>
               &lt;&lt; &quot;ymax: &quot; &lt;&lt; boxBounds.ymax &lt;&lt; std::endl<br>
               &lt;&lt; &quot;zmin: &quot; &lt;&lt; boxBounds.zmin &lt;&lt; &quot; &quot;<br>
               &lt;&lt; &quot;zmax: &quot; &lt;&lt; boxBounds.zmax &lt;&lt; std::endl;<br>
<br>
    // build OBB Tree locator<br>
    vtkSmartPointer&lt;vtkOBBTree&gt; tree = vtkSmartPointer&lt;vtkOBBTree&gt;::New();<br>
    tree-&gt;SetDataSet(polydata);<br>
    tree-&gt;BuildLocator();<br>
<br>
    // calculate area<br>
    double area = 0;<br>
    for (double zdir = boxBounds.zmin; zdir &lt; boxBounds.zmax; zdir = zdir +<br>
resolution)<br>
    {<br>
        for (double ydir = boxBounds.ymin; ydir &lt; boxBounds.ymax; ydir =<br>
ydir + resolution)<br>
        {<br>
            // Line to intersect with<br>
            double p1[3] = {boxBounds.xmin, ydir + resolution/2, zdir +<br>
resolution/2,};<br>
            double p2[3] = {boxBounds.xmax, ydir + resolution/2, zdir +<br>
resolution/2,};<br>
            //Find intersection points<br>
            vtkSmartPointer&lt;vtkPoints&gt; intersectPoints =<br>
vtkSmartPointer&lt;vtkPoints&gt;::New();<br>
            tree-&gt;IntersectWithLine(p1, p2, intersectPoints, NULL);<br>
            // this bit will draw a rough approximation of the shape<br>
            if (intersectPoints-&gt;GetNumberOfPoints() &gt; 0)<br>
            {<br>
                cout &lt;&lt; &quot;#&quot;;<br>
                area++;<br>
            }<br>
            else<br>
            {<br>
                cout &lt;&lt; &quot; &quot;;<br>
            }<br>
        }<br>
        cout &lt;&lt; std::endl;<br>
    }<br>
    // output how many hits, which for a resolution of 1 should equal<br>
something like 1mm^2<br>
    cout &lt;&lt; &quot;area: &quot; &lt;&lt; area * resolution * resolution &lt;&lt; std::endl;<br>
<br>
    return EXIT_SUCCESS;<br>
}<br>
<br>
<br>
<br>
_______________________________________________<br>
Powered by <a href="http://www.kitware.com" target="_blank">www.kitware.com</a><br>
<br>
Visit other Kitware open-source projects at <a href="http://www.kitware.com/opensource/opensource.html" target="_blank">http://www.kitware.com/opensource/opensource.html</a><br>
<br>
Please keep messages on-topic and check the VTK FAQ at: <a href="http://www.vtk.org/Wiki/VTK_FAQ" target="_blank">http://www.vtk.org/Wiki/VTK_FAQ</a><br>
<br>
Follow this link to subscribe/unsubscribe:<br>
<a href="http://www.vtk.org/mailman/listinfo/vtkusers" target="_blank">http://www.vtk.org/mailman/listinfo/vtkusers</a><br>
</blockquote></div><br></div></div>