Skip to content
Snippets Groups Projects
Select Git revision
  • 38b5a33e5279ca5baf6e5fbc354026b61d1757d7
  • master default protected
  • develop protected
  • cmake_boost_refactor
  • ubuntu_ci
  • mmtf
  • non-orthogonal-maps
  • no_boost_filesystem
  • data_viewer
  • 2.11.1
  • 2.11.0
  • 2.10.0
  • 2.9.3
  • 2.9.2
  • 2.9.1
  • 2.9.0
  • 2.8.0
  • 2.7.0
  • 2.6.1
  • 2.6.0
  • 2.6.0-rc4
  • 2.6.0-rc3
  • 2.6.0-rc2
  • 2.6.0-rc
  • 2.5.0
  • 2.5.0-rc2
  • 2.5.0-rc
  • 2.4.0
  • 2.4.0-rc2
29 results

export_entity_to_density.cc

Blame
  • generate_map_iso_spec.py 6.97 KiB
    #------------------------------------------------------------------------------
    # This file is part of the OpenStructure project <www.openstructure.org>
    #
    # Copyright (C) 2008-2010 by the OpenStructure authors
    #
    # This library is free software; you can redistribute it and/or modify it under
    # the terms of the GNU Lesser General Public License as published by the Free
    # Software Foundation; either version 3.0 of the License, or (at your option)
    # any later version.
    # This library is distributed in the hope that it will be useful, but WITHOUT
    # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    # FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
    # details.
    #
    # You should have received a copy of the GNU Lesser General Public License
    # along with this library; if not, write to the Free Software Foundation, Inc.,
    # 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
    #------------------------------------------------------------------------------
    #
    # Author: Ansgar Philippsen
    #
    # automatically generate iso-contouring marching cube specs
    #
    
    import math
    
    # cube definition
    
    # corners:
    #     5        6
    #      -------
    #     /.     /|
    #    / .    / |
    #  1 ------ 2 |
    #   |  ....|..|
    #   | .4   | / 7
    #   |.     |/
    #    ------
    #  0        3
    
    # vertices:              
    #      ---9---
    #     5.     6|
    #    / 8    / |
    #    ---1--   10
    #   |  ..11|..|
    #   0 4    2 7  
    #   |.     |/
    #    --3---
    
    # faces     2
    #          .       
    #      -------
    #     /      /|
    #    /   1  / |
    #    ------  .|.. 5
    #4..|      |  |
    #   |  0   | / 
    #   |      |/.
    #    ------   3
    
    corner_coord=[[0,0,0],[0,1,0],[1,1,0],[1,0,0],
                   [0,0,1],[0,1,1],[1,1,1],[1,0,1]]
    
    edge_corner=[[0,1],[1,2],[2,3],[3,0],
                    [0,4],[1,5],[2,6],[3,7],
                    [4,5],[5,6],[6,7],[4,7]]
    
    face_edges=[[0,1,2,3],[1,5,9,6],[9,8,11,10],
                [11,7,3,4],[4,8,5,0],[7,2,6,10]]
    
    header_code="""
    // automatically generated by generate_map_iso_spec.py
    // do not edit directly
    
    #include "map_iso_gen.hh"
    
    namespace ost { namespace gfx { namespace map_iso {
    
    template<int N>
    void AddLinesAndFaces(IndexedVertexArray& va, // vertex array
    		      unsigned int vertex_id[12] // this list of vertex ids
    		      );
    """
    
    isocube_header_code="""
    template<> 
    void AddLinesAndFaces<%d>(IndexedVertexArray& va,unsigned int vertex_id[12] )
    {
    """
    
    isocube_addline_code="""  va.AddLine(vertex_id[%d],vertex_id[%d]);
    """
    
    isocube_addface_code="""  va.AddTriN(vertex_id[%d],vertex_id[%d],vertex_id[%d]);
    """
    
    isocube_debug_code="""
    #ifdef MAP_ISO_DEBUG
      if(vertex_id[%d]==0) std::cerr << \"ISO_DEBUG: \" << %d << \" \" << %d << std::endl;
      if(vertex_id[%d]==0) std::cerr << \"ISO_DEBUG: \" << %d << \" \" << %d << std::endl;
      if(vertex_id[%d]==0) std::cerr << \"ISO_DEBUG: \" << %d << \" \" << %d << std::endl;
    #endif
    """
    
    isocube_footer_code="}\n"
    
    flist_header_code="""
    void GenerateLFList(AddLFList& lfl)
    {
      lfl.clear();
    """
    
    flist_code="  lfl.push_back(AddLinesAndFaces<%d>);\n"
    
    flist_footer_code="""
    }
    """
    
    footer_code="""
    }}} // ns
    """
    
    def vadd(v1,v2):
        return [v1[0]+v2[0],
                v1[1]+v2[1],
                v1[2]+v2[2]]
    
    def vsub(v1,v2):
        return [v1[0]-v2[0],
                v1[1]-v2[1],
                v1[2]-v2[2]]
    
    def vmul(s,v1):
        return [v1[0]*s,
                v1[1]*s,
                v1[2]*s]
    
    def vdot(v1,v2):
        return v1[0]*v2[0]+v1[1]*v2[1]+v1[2]*v2[2]
    
    def vcross(v1,v2):
        return [v1[1]*v2[2]-v2[1]*v1[2],
    	    v1[2]*v2[0]-v2[2]*v1[0],
    	    v1[0]*v2[1]-v2[0]*v1[1]]
    
    def vnorm(v1):
        len2=v1[0]*v1[0]+v1[1]*v1[1]+v1[2]*v1[2]
        return vmul(1.0/math.sqrt(len2),v1)
    
    def work(spec_file,pattern):
    
        corner_bit=[0,0,0,0,0,0,0,0]
        for i in range(8):
            if pattern & (1<<i):
                corner_bit[i]=1
    
        edge_bit=[0,0,0,0,0,0,0,0,0,0,0,0]
        edge_list=[]
        for i in range(12):
            if corner_bit[edge_corner[i][0]] != corner_bit[edge_corner[i][1]]:
                edge_bit[i]=1
                edge_list.append(i)
    
        spec_file.write(isocube_header_code%pattern)
    
        # first the lines
        edge_pairs=[]
        for e1 in edge_list:
            for e2 in edge_list:
                if e1>e2:
                    for f in face_edges:
                        if e1 in f and e2 in f:
                            # line across a face
                            edge_pairs.append([e1,e2])
                            spec_file.write(isocube_addline_code%(e1,e2))
    
        # find line-loop(s)
        while len(edge_pairs)>0:
            edge_loop=[]
            edge_loop.extend(edge_pairs[0])
            edge_pairs.remove(edge_pairs[0])
            closed=False
            while not closed:
                for ep in edge_pairs:
                    if ep[0]==edge_loop[len(edge_loop)-1]:
                        if ep[1]==edge_loop[0]:
                            closed=True
                        else:
                            edge_loop.append(ep[1])
                        edge_pairs.remove(ep)
                        break
                    elif ep[1]==edge_loop[len(edge_loop)-1]:
                        if ep[0]==edge_loop[0]:
                            closed=True
                        else:
                            edge_loop.append(ep[0])
                        edge_pairs.remove(ep)
                        break
    
            # find correct orientation 
            # assemble dir0 from middle of edge and the higher value corner
            edge_id0 = edge_loop[0]
            v00 = edge_corner[edge_id0][0]
            v01 = edge_corner[edge_id0][1]
            e0_pos = vmul(0.5,vadd(corner_coord[v00],corner_coord[v01]))
            e1_pos=[0,0,0]
            if corner_bit[v00]==1:
                e1_pos=corner_coord[v00]
            else:
                e1_pos=corner_coord[v01]
            dir0 = vnorm(vsub(e1_pos,e0_pos))
            # assemble dir1 from the cross product of the lines of the
            # edge_loop
            edge_id1 = edge_loop[1]
            v10 = edge_corner[edge_id1][0]
            v11 = edge_corner[edge_id1][1]
            edge_id2 = edge_loop[2]
            v20 = edge_corner[edge_id2][0]
            v21 = edge_corner[edge_id2][1]
            e1_pos = vmul(0.5,vadd(corner_coord[v10],corner_coord[v11]))
            e2_pos = vmul(0.5,vadd(corner_coord[v20],corner_coord[v21]))
            e10 = vsub(e0_pos,e1_pos)
            e12 = vsub(e2_pos,e1_pos)
            dir1 = vnorm(vcross(e10,e12))
            # this is the actual orientation check
            if vdot(dir0,dir1)<0.0:
                edge_loop.reverse()
            # dump code to file
            for i in range(len(edge_loop)-2):
                spec_file.write(isocube_addface_code%(edge_loop[0],edge_loop[i+2],edge_loop[i+1]))
                spec_file.write(isocube_debug_code%(edge_loop[0],edge_loop[0],pattern,
                                                    edge_loop[i+2],edge_loop[i+2],pattern,
                                                    edge_loop[i+1],edge_loop[i+1],pattern))
                                                    
                
        spec_file.write(isocube_footer_code)
        
    
    spec_file=file("map_iso_spec.hh","w")
    
    spec_file.write(header_code)
        
    for i in range(256):
        work(spec_file,i)
    
    spec_file.write(flist_header_code)
    for i in range(256):
        spec_file.write(flist_code%i)
    spec_file.write(flist_footer_code)
    
    spec_file.write(footer_code)