; docformat = 'rst' ; ; NAME: ; readVer ; PURPOSE: ; Read a 3-D shape model file in VER format into a structure ;+ ; :Description: ; Read a 3-D shape model file in VER format into a structure ; ; :Categories: ; Disk I/O, Shape Models ; ; :Params: ; FILE: in, required, type=string ; A path to the file containing the 3-D shape model in VER format ; ; :Returns: Upon success, a structure containing the 3-D shape model. Fields are:: ; .VERTEX: A structure with Information on Vertex:: ; .N = Number of Vertex ; .XYZ= Cartesian coordinates of the vertex ; .FACET: A structure with Information on Facet:: ; .N = Number of Facets ; .CON = Connectivity array ([N_vertex, ID_vertex....]) ; .LIST = Connectivity array ([ID_vertex....]) ; .NORMAL= Array of facet normals (only if keyword NORMALS is set) ; .EDGES: A structure with Information on Edges (only if keyword EDGES is set):: ; .N = Number of Edges ; .vertex= Array of vertex per edge ; .facet = Array of facets per edge ; .edge = Array of edges per facet ; If the reading fails, it returns an error code:: ; 1 : Syntax error ; 2 : File cannot be read ; ; :Keywords: ; edges: in, optional, type=boolean, default=0 ; Trigger computation of shape edges properties. ; normals: in, optional, type=boolean, default=0 ; Trigger computation of facet normal vectors. ; ; :Examples: ; Read a shape model file and print the number of vertex and facets:: ; IDL> model = readVer('myfile') ; IDL> print, model.vertex.n, model.facet.n ; ; :Uses: ; ver_edges ; ; :Author: ; B.Carry (OCA) ; ; :History: ; Change History:: ; Original Version written in 2007, B. Carry (ESO/LESIA) ; 2013 Mar. - B.Carry (IMCCE) - Edges (Facet-Side Links) computation added ; 2013 Nov. - B.Carry (IMCCE) - Model structure modified ; 2017 July - B.Carry (OCA) - Idl2 added and bullet-proof tests ;- function readVer, file, edges=edges, normals=normals COMPILE_OPT hidden, idl2 ;-----------------------------------------------------------------------------------------------; ;-----------------------------------------------------------------------------------------------; ;--- TAG --- I -- Initialization And Input Verification -----------------------; ;-----------------------------------------------------------------------------------------------; ;-----------------------------------------------------------------------------------------------; ;--I.1-- Input Syntax Verification ----------------------------------------------------------- if n_params() lt 1 then begin message, 'Syntax : model = readVer( path [, /edges, /normals] )' return, 1 endif ;--I.2-- Test Input File Existance ----------------------------------------------------------- if not file_test(file,/READ) then begin message, 'ERROR: readVer cannot read the input file: '+strTrim(file,2) return, 2 endif ;-----------------------------------------------------------------------------------------------; ;-----------------------------------------------------------------------------------------------; ;--- TAG --- II -- Read the 3-D Shape Model File -----------------------; ;-----------------------------------------------------------------------------------------------; ;-----------------------------------------------------------------------------------------------; ;--II.1-- Open the File ---------------------------------------------------------------------- openR, idIn, file, /Get_Lun ;--II.2-- Number of Facets and Vertices ------------------------------------------------------ nbVertex = 0L nbFacet = 0L readf, idIn, nbVertex, nbFacet ;--II.3-- Read Vertex Cartesian Coordinates -------------------------------------------------- objVertex = fltarr(3, nbVertex) for kVert=0L, nbVertex-1L do begin readf, idIn, posX, posY, posZ objVertex[0,kVert] = posX objVertex[1,kVert] = posY objVertex[2,kVert] = posZ endfor ;--II.4-- Identify Type of VER Format -------------------------------------------- line = ' ' readf, idIn, line split = strSplit(line, /RegEx, /Extract, count=nbSplit) ;--II.5-- Read Polygons Connectivity --------------------------------------------- kPoly = 0L MAXPOL = 99999999L objPolygons = lonarr(MAXPOL) listFacet = lonarr(3,MAXPOL/3.) ;--II.5.1-- DAMIT Format ----------------------------------------------------------- if nbSplit eq 3 then begin ;--II.5.1/a-- Set Facets to Triangles nbSide = 3 ;--II.5.1/b-- Save First Line (Read for Test Purpose) ;--II.5.1/b.1-- Split Current Line into Sides ReadNumVert = lonarr(nbSide) reads, line, ReadNumVert ;--II.5.1/b.2-- Number of Side objPolygons[kPoly] = nbSide ;--II.5.1/b.3-- Side Indices for kVert=1L, nbSide do objPolygons[kPoly+kVert] = ReadNumVert[kVert-1]-1 listFacet[*,kPoly] = objPolygons[kPoly+[1,2,3]] ;--II.5.1/b.4-- Side Increment kPoly += (nbSide+1) ;-[nbSide + nbSide * Index ] = 4 ;--II.5.1/c-- Read All Lines for kFacet=1L, NbFacet-1 do begin ;--II.5.1/c.1-- Split Current Line into Sides ReadNumVert = lonarr(nbSide) readf, idIn, ReadNumVert ;--II.5.1/c.2-- Number of Side objPolygons[kPoly] = nbSide ;--II.5.1/c.3-- Side Indices for kVert=1L, nbSide do objPolygons[kPoly+kVert] = ReadNumVert[kVert-1]-1 listFacet[*,kFacet] = objPolygons[kPoly+[1,2,3]] ;--II.5.1/c.4-- Side Increment kPoly += (nbSide+1) ;-[nbSide + nbSide * Index ] = 4 endfor ;--II.5.2-- Non DAMIT Format ------------------------------------------------------- endif else begin ;--II.5.2/a-- Number of Sides was Already Read ;--II.5.2/b-- Save First Line (Read for Test Purpose) ;--II.5.2/b.1-- Split Current Line into Sides reads, line, nbSide ReadNumVert = lonarr(nbSide) readf, idIn, ReadNumVert ;--II.5.2/b.2-- Convert Facets into Triangle (if more than a segment) for kVert=1L, nbSide-2L do begin ;--II.5.2/b.2a-- Number of Sides - Set to Triangle objPolygons[kPoly] = 3 ;--II.5.2/b.2b-- Side Indices objPolygons[kPoly+1L] = ReadNumVert[0] -1 ;-Common Vertex for All Sub-Facets objPolygons[kPoly+2L] = ReadNumVert[kVert] -1 ;-The two Others CHANGE for each Sub-Facet objPolygons[kPoly+3L] = ReadNumVert[kVert+1L]-1 ;- NB '-1' to switch from 1:N to 0:N-1 (IDL) listFacet[*,kPoly] = objPolygons[kPoly+[1,2,3]] ;--II.5.2/b.2c-- Side Increment kPoly += 4L endfor ;--II.5.2/c-- Read All Lines for kFacet=1L, NbFacet-1L do begin ;--II.5.2/c.1-- Split Current Line into Sides readf, idIn, nbSide ReadNumVert = lonarr(nbSide) readf, idIn, ReadNumVert ;--II.5.2/c.2-- Convert Facets into Triangle (if more than a segment) for kVert=1L, nbSide-2L do begin ;--II.5.2/c.2a-- Number of Sides - Set to Triangle objPolygons[kPoly] = 3 ;--II.5.2/c.2b-- Side Indices objPolygons[kPoly+1L] = ReadNumVert[0] -1 ;-Common Vertex for All Sub-Facets objPolygons[kPoly+2L] = ReadNumVert[kVert] -1 ;-The two Others CHANGE for each Sub-Facet objPolygons[kPoly+3L] = ReadNumVert[kVert+1L]-1 ;- NB '-1' to switch from 1:N to 0:N-1 (IDL) ;--II.5.2/c.2c-- Side Increment kPoly += 4L endfor ;-End Loop over Vertex endfor ;-End Loop over Facet endelse ;--II.6-- Close Shape Model File ------------------------------------------------- close, idIn free_lun, idIn ;--II.7-- Shorten Polygons Connectitivy Array ------------------------------------ objPolygons = objPolygons[0L:kPoly-1L] listFacet=listFacet[*,0:nbFacet-1] ;-----------------------------------------------------------------------------------------------; ;-----------------------------------------------------------------------------------------------; ;--- TAG --- III -- Optionnal Computation: Connectivity, Normals -----------------------; ;-----------------------------------------------------------------------------------------------; ;-----------------------------------------------------------------------------------------------; ;--III.1-- Compute Facet Neighboring Properties ----------------------------------- if keyword_set(edges) then edges = ver_edges({ vertex:{ n:nbVertex, xyz:objVertex }, $ facet: { n:nbFacet, con:objPolygons} } ) ;--III.2-- Compute Facet Normals -------------------------------------------------- if keyword_set(normals) then vertical = facetnormals( objVertex, objPolygons ) ;-----------------------------------------------------------------------------------------------; ;-----------------------------------------------------------------------------------------------; ;--- TAG --- IV -- Output Cleaning and Connectivity Computation -----------------------; ;-----------------------------------------------------------------------------------------------; ;-----------------------------------------------------------------------------------------------; ;--IV.1-- Vertex Structure for Output -------------------------------------------- vertex = { n:nbVertex, xyz:objVertex } ;--IV.2-- Facet Structure for Output --------------------------------------------- if keyword_set(normals) then facet = { n:nbFacet, con:objPolygons, list:listFacet, normal:vertical } $ else facet = { n:nbFacet, con:objPolygons, list:listFacet } ;--IV.3-- Model Structure for Output --------------------------------------------- if keyword_set(edges) then model = { vertex:vertex, facet:facet, edges:edges } $ else model = { vertex:vertex, facet:facet } ;--IV.4-- Export Shape Model Structure ------------------------------------------- return, model end