<commit_before>/*
 * Created on Jun 25, 2003
 *
 * To change the template for this generated file go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */
package com.vzome.core.viewing;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.StringTokenizer;

import com.vzome.core.algebra.AlgebraicMatrix;
import com.vzome.core.algebra.AlgebraicVector;
import com.vzome.core.math.Polyhedron;
import com.vzome.core.math.VefParser;
import com.vzome.core.math.symmetry.Axis;
import com.vzome.core.math.symmetry.Direction;
import com.vzome.core.math.symmetry.IcosahedralSymmetry;
import com.vzome.core.math.symmetry.Symmetry;
import com.vzome.core.parts.StrutGeometry;

/**
 * @author vorth
 * 
 * To change the template for this generated type comment go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */
public class ExportedVEFShapes extends AbstractShapes
{
    public static final String MODEL_PREFIX = "com/vzome/core/parts/";

    private static final String NODE_MODEL = "/connector.vef";
    
    private final File prefsFolder;
    
    private final AbstractShapes fallback;
        
    public ExportedVEFShapes( File prefsFolder, String pkgName, String name, String alias, Symmetry symm )
    {
        super( pkgName, name, alias, symm );
        this .prefsFolder = prefsFolder;
        if ( symm instanceof IcosahedralSymmetry)
            this .fallback = new ScriptedShapes( prefsFolder, pkgName, name, (IcosahedralSymmetry) symm );
        else
            this .fallback = null;
    }
    
    public ExportedVEFShapes( File prefsFolder, String pkgName, String name, Symmetry symm )
    {
        this( prefsFolder, pkgName, name, null, symm );
    }
    
    public ExportedVEFShapes( File prefsFolder, String pkgName, String name, Symmetry symm, AbstractShapes fallback )
    {
        super( pkgName, name, symm );
        this .prefsFolder = prefsFolder;
        this .fallback = fallback;
    }
    
    protected Polyhedron buildConnectorShape( String pkgName )
    {
        String path = pkgName + NODE_MODEL;       
        InputStream bytes = null;
        File shapeFile = new File( this .prefsFolder, "Shapes/" + path );
        if ( shapeFile .exists() )
            try {
                bytes = new FileInputStream( shapeFile );
            	bytes .close();
            } catch ( Exception e1 ) {
                // TODO log this... should never happen?
                e1.printStackTrace();
            }
        else {
            path = MODEL_PREFIX + path;
            bytes = Thread.currentThread() .getContextClassLoader().getResourceAsStream( path );
        }
        if ( bytes == null )
            if ( this .fallback != null )
                return this .fallback .buildConnectorShape( pkgName );
            else
                throw new IllegalStateException( "missing script: " + path );

        ByteArrayOutputStream out = new ByteArrayOutputStream();
        byte[] buf = new byte[1024];
        int num;
        try {
            while ( ( num = bytes .read( buf, 0, 1024 )) > 0 )
                out .write( buf, 0, num );
        } catch ( IOException e ) {
            throw new IllegalStateException( "IO exception: " + path );
        }
        String vefData = new String( out .toByteArray() );
        
        VefToShape parser = new VefToShape();
        parser .parseVEF( vefData, mSymmetry .getField() );

        return parser .getConnectorPolyhedron();
    }

    protected StrutGeometry createStrutGeometry( Direction dir )
    {
        // else is default, let's try to improve on that

        String script = mPkgName + "/" + dir .getName() + ".vef";
        InputStream bytes = null;
        File shapeFile = new File( this .prefsFolder, "Shapes/" + script );
        if ( shapeFile .exists() )
            try {
                bytes = new FileInputStream( shapeFile );
                bytes .close();
            } catch ( Exception e1 ) {
                // TODO log this... should never happen?
                e1.printStackTrace();
            }
        else {
            script = MODEL_PREFIX + script;
            bytes = Thread.currentThread() .getContextClassLoader().getResourceAsStream( script );
        }
        if ( bytes == null )
            if ( this .fallback != null )
                return this .fallback .createStrutGeometry( dir );
            else
                return super .createStrutGeometry( dir );

        ByteArrayOutputStream out = new ByteArrayOutputStream();
        byte[] buf = new byte[1024];
        int num;
        try {
            while ( ( num = bytes .read( buf, 0, 1024 )) > 0 )
                out .write( buf, 0, num );
        } catch ( IOException e ) {
            return super .createStrutGeometry( dir );
        }
        String vefData = new String( out .toByteArray() );
        
        VefToShape parser = new VefToShape();
        parser .parseVEF( vefData, mSymmetry .getField() );

        return parser .getStrutGeometry( dir .getAxis( Symmetry .PLUS, 0 ) .normal() );
    }
    
    /*
     * The VEF file format parsed here is an "extended profile" of the usual format.
     * First, it is a profile because the only "balls" (not vertices) present in the file
     * should be those that correspond to panel vertices that must track the location of the end
     * of the strut.  Second, it is an extension because the "tip" index at the end indicates the
     * vertex corresponding to the end ball position of the strut as modeled.
     * 
     * The tip vector is subtracted from all the strut-end-tracking ("ball") vectors, in the prototype
     * polyhedron.  Then, when a new length polyhedron is required, the scaled prototype vector is added
     * to those ball vectors again, for the final polyhedron.
     */
    
    private class VefToShape extends VefParser
    {                
        private Set stretchVertexIndices = new HashSet();
        
        private List vertices = new ArrayList();
        
        private List faces = new ArrayList();
        
        public StrutGeometry getStrutGeometry( AlgebraicVector prototype )
        {
            return new ExportedVEFStrutGeometry( vertices, faces, prototype, stretchVertexIndices, mSymmetry .getField() );
        }
        
        public Polyhedron getConnectorPolyhedron()
        {
            Polyhedron result = new Polyhedron( mSymmetry .getField() );
            for ( int i = 0; i < vertices .size(); i ++ )
            {<commit_msg>ExportedVEFShapes fixes for loading user-defined shapes, and refactoring into loadVefData()<commit_after>/*
 * Created on Jun 25, 2003
 *
 * To change the template for this generated file go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */
package com.vzome.core.viewing;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.logging.Logger;

import com.vzome.core.algebra.AlgebraicMatrix;
import com.vzome.core.algebra.AlgebraicVector;
import com.vzome.core.math.Polyhedron;
import com.vzome.core.math.VefParser;
import com.vzome.core.math.symmetry.Axis;
import com.vzome.core.math.symmetry.Direction;
import com.vzome.core.math.symmetry.IcosahedralSymmetry;
import com.vzome.core.math.symmetry.Symmetry;
import com.vzome.core.parts.StrutGeometry;

/**
 * @author vorth
 */
public class ExportedVEFShapes extends AbstractShapes
{
    public static final String MODEL_PREFIX = "com/vzome/core/parts/";

    private static final String NODE_MODEL = "connector";
    
    private final File prefsFolder;
    
    private final AbstractShapes fallback;
    
    static Logger logger = Logger.getLogger( "com.vzome.core.viewing.shapes" );
        
    public ExportedVEFShapes( File prefsFolder, String pkgName, String name, String alias, Symmetry symm )
    {
        super( pkgName, name, alias, symm );
        this .prefsFolder = prefsFolder;
        if ( symm instanceof IcosahedralSymmetry)
            this .fallback = new ScriptedShapes( prefsFolder, pkgName, name, (IcosahedralSymmetry) symm );
        else
            this .fallback = null;
    }
    
    public ExportedVEFShapes( File prefsFolder, String pkgName, String name, Symmetry symm )
    {
        this( prefsFolder, pkgName, name, null, symm );
    }
    
    public ExportedVEFShapes( File prefsFolder, String pkgName, String name, Symmetry symm, AbstractShapes fallback )
    {
        super( pkgName, name, symm );
        this .prefsFolder = prefsFolder;
        this .fallback = fallback;
    }
    
    protected Polyhedron buildConnectorShape( String pkgName )
    {
    	String vefData = loadVefData( NODE_MODEL );
    	if ( vefData != null ) {
            VefToShape parser = new VefToShape();
            parser .parseVEF( vefData, mSymmetry .getField() );
            return parser .getConnectorPolyhedron();
    	}
        if ( this .fallback != null )
            return this .fallback .buildConnectorShape( pkgName );
        else
            throw new IllegalStateException( "missing connector shape: " + pkgName );
    }

    protected StrutGeometry createStrutGeometry( Direction dir )
    {
    	String vefData = loadVefData( dir .getName() );
    	if ( vefData != null ) {
            VefToShape parser = new VefToShape();
            parser .parseVEF( vefData, mSymmetry .getField() );
            return parser .getStrutGeometry( dir .getAxis( Symmetry .PLUS, 0 ) .normal() );
    	}
    	else  if ( this .fallback != null )
    		return this .fallback .createStrutGeometry( dir );
    	else
    		return super .createStrutGeometry( dir );
    }

    protected String loadVefData( String name )
    {
        String script = mPkgName + "/" + name + ".vef";
        File shapeFile = new File( this .prefsFolder, "Shapes/" + script );
        InputStream stream = null;
        try {
            if ( shapeFile .exists() )
                stream = new FileInputStream( shapeFile );
            else {
                script = MODEL_PREFIX + script;
                stream = Thread.currentThread() .getContextClassLoader().getResourceAsStream( script );
            }
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            byte[] buf = new byte[1024];
            int num;
            while ( ( num = stream .read( buf, 0, 1024 )) > 0 )
            	out .write( buf, 0, num );
            return new String( out .toByteArray() );

        } catch (Exception e) {
            logger .fine( "Failure loading VEF data from " + shapeFile );
		} finally {
			if ( stream != null )
				try {
					stream .close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		}
        return null;
    }

    /*
     * The VEF file format parsed here is an "extended profile" of the usual format.
     * First, it is a profile because the only "balls" (not vertices) present in the file
     * should be those that correspond to panel vertices that must track the location of the end
     * of the strut.  Second, it is an extension because the "tip" index at the end indicates the
     * vertex corresponding to the end ball position of the strut as modeled.
     * 
     * The tip vector is subtracted from all the strut-end-tracking ("ball") vectors, in the prototype
     * polyhedron.  Then, when a new length polyhedron is required, the scaled prototype vector is added
     * to those ball vectors again, for the final polyhedron.
     */
    
    private class VefToShape extends VefParser
    {                
        private Set stretchVertexIndices = new HashSet();
        
        private List vertices = new ArrayList();
        
        private List faces = new ArrayList();
        
        public StrutGeometry getStrutGeometry( AlgebraicVector prototype )
        {
            return new ExportedVEFStrutGeometry( vertices, faces, prototype, stretchVertexIndices, mSymmetry .getField() );
        }
        
        public Polyhedron getConnectorPolyhedron()
        {
            Polyhedron result = new Polyhedron( mSymmetry .getField() );
            for ( int i = 0; i < vertices .size(); i ++ )
            {
{'fraction_non_alphanumeric': 0.0887058450815777, 'fraction_numerical': 0.004197687311896087, 'mean_word_length': 2.3211467648606, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 18, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1460688', 'n_tokens_mistral': 3643, 'n_tokens_neox': 3457, 'n_words': 1114}