// Aqsis
// Copyright (c) 1997 - 2001, Paul C. Gregory
//
// Contact: pgregory@aqsis.com
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public
// License as published by the Free Software Foundation; either
// version 2 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
// General Public License for more details.
//
// You should have received a copy of the GNU General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

/**
 * Copyright (C) 2006-2007  NTT DATA CORPORATION
 * 
 * Version: 1.0.0 2007/04/01
 *  
 */
package net.cellcomputing.himawari.library;

import static net.cellcomputing.himawari.library.RiGlobal.*;
import static net.cellcomputing.himawari.library.EqEnvVars.*;
import static net.cellcomputing.himawari.library.EqVariableClass.*;
import static net.cellcomputing.himawari.library.EqVariableType.*;
import static net.cellcomputing.himawari.library.EqSplitDir.*;

import net.cellcomputing.himawari.accessory.STLVector;
import net.cellcomputing.himawari.accessory.primitive.p_String;
import net.cellcomputing.himawari.accessory.primitive.p_float;
import net.cellcomputing.himawari.accessory.primitive.p_int;
import net.cellcomputing.himawari.library.types.CqColor;
import net.cellcomputing.himawari.library.types.CqMatrix;
import net.cellcomputing.himawari.library.types.CqVector2D;
import net.cellcomputing.himawari.library.types.CqVector3D;
import net.cellcomputing.himawari.library.types.CqVector4D;

/**
 * 
 * Abstract base surface class, which provides interfaces to a geometric surface. <br> 
 * 抽象的なベース表面のクラス。(そのクラスはインタフェースを幾何学上surfaceoptionsに供給します)。
 * 
 * @author NTT DATA Corporation
 */
public abstract strictfp class CqSurface extends CqBasicSurface {

	protected STLVector<CqParameter>	m_aUserParams = new STLVector<CqParameter>( CqParameter.class );	///< Storage for user defined paramter variables.
	protected int[] m_aiStdPrimitiveVars = new int[ EnvVars_Last ];			///< Quick lookup index into the primitive variables table for standard variables.

    protected static long RIH_P		= "P".hashCode();
    protected static long RIH_N		= "N".hashCode();
    protected static long RIH_CS		= "Cs".hashCode();
    protected static long RIH_OS		= "Os".hashCode();
    protected static long RIH_S		= "s".hashCode();
    protected static long RIH_T		= "t".hashCode();
    protected static long RIH_U		= "u".hashCode();
    protected static long RIH_V		= "v".hashCode();
	
	//************************************************************************//
	//*** コンストラクタの定義
	//************************************************************************//
    
    /**
	 * デフォルトコンストラクタ
	 */
	public CqSurface() {
		
		super();
	    // Nullify the standard primitive variables index table.
	    int i;
	    for ( i = 0; i < EnvVars_Last; i++ ){
	        m_aiStdPrimitiveVars[ i ] = -1;
	    }
	}
	
	/**
	 * コピーコンストラクタ
	 * @param From	コピー元
	 */
	public CqSurface( final CqSurface From )
	{
		this.assignment( From );
	}
	
	
	/* (non-Javadoc)
	 * @see net.cellcomputing.himawari.library.CqBasicSurface#destruct()
	 */
	public void destruct()
	{
		for( CqParameter iUP : m_aUserParams ){
			if(iUP != null) //2006/01/04 追加 nttdata
				iUP.destruct();			
		}
		super.destruct();	//2006/01/04 追加 nttdata
	}
	
	//************************************************************************//
	//*** メソッドの定義
	//************************************************************************//

	/**
	 * 同メソッドをオーバーロード。<br>
	 * 初期値として引数にtrueを与える。
	 * 
	 */
	public final void SetDefaultPrimitiveVariables(){
		SetDefaultPrimitiveVariables( true );
	}
	
	
	/**
	 * 
	 * Set the default values (where available) from the attribute state
	 * for all standard primitive variables.
	 * デフォルト値の設定。
	 * 
	 * @param bUseDef_st	s,t値の設定の許可。
	 */
	@SuppressWarnings("unchecked")
	//nttdata 高速化
//	public void SetDefaultPrimitiveVariables( boolean bUseDef_st )
//	{
//	    int bUses = Uses();
//	    // Set default values for all of our parameters
//
//	    // s and t default to four values, if the particular surface type requires different it is up
//	    // to the surface to override or change this after the fact.
//	    if ( USES( bUses, EnvVars_s ) && bUseDef_st && !bHasVar(EnvVars_s) )
//	    {
//	        AddPrimitiveVariable( new CqParameterTypedVarying( "s", new EqVariableType( type_float ), p_float.class, p_float.class ));
//	        s().SetSize( 4 );
//	        for ( int i = 0; i < 4; i++ )
//	        	((p_float)( s().pValue() [ i ])).value = m_pAttributes.GetFloatAttribute( "System", "TextureCoordinates" ) [ i * 2 ];
//	    }
//
//	    if ( USES( bUses, EnvVars_t ) && bUseDef_st && !bHasVar(EnvVars_t))
//	    {
//	        AddPrimitiveVariable( new CqParameterTypedVarying( "t", new EqVariableType( type_float ), p_float.class, p_float.class ));
//	        t().SetSize( 4 );
//	        for ( int i = 0; i < 4; i++ )
//	        	((p_float)( t().pValue() [ i ])).value = m_pAttributes.GetFloatAttribute( "System", "TextureCoordinates" ) [ ( i * 2 ) + 1 ];
//	    }
//
//	    if ( USES( bUses, EnvVars_u ) )
//	    {
//	        AddPrimitiveVariable( new CqParameterTypedVarying( "u", new EqVariableType( type_float ), p_float.class, p_float.class ));
//	        u().SetSize( 4 );
//	        
//	        ((p_float)( u().pValue() [ 0 ])).value = 0.0f;
//	        ((p_float)( u().pValue() [ 2 ])).value = 0.0f;
//	        ((p_float)( u().pValue() [ 1 ])).value = 1.0f;
//	        ((p_float)( u().pValue() [ 3 ])).value = 1.0f;
//	        
//	    }
//
//	    if ( USES( bUses, EnvVars_v ) )
//	    {
//	        AddPrimitiveVariable( new CqParameterTypedVarying( "v", new EqVariableType( type_float ), p_float.class, p_float.class ));
//	        v().SetSize( 4 );
//	        ((p_float)( v().pValue() [ 0 ])).value = 0.0f;
//	        ((p_float)( v().pValue() [ 1 ])).value = 0.0f;
//	        ((p_float)( v().pValue() [ 2 ])).value = 1.0f;
//	        ((p_float)( v().pValue() [ 3 ])).value = 1.0f;
//	    }
//	}
	public void SetDefaultPrimitiveVariables( boolean bUseDef_st )
	{
	    int bUses = Uses();
	    // Set default values for all of our parameters

	    // s and t default to four values, if the particular surface type requires different it is up
	    // to the surface to override or change this after the fact.
	    if ( USES( bUses, EnvVars_s ) && bUseDef_st && !bHasVar(EnvVars_s) )
	    {
	        AddPrimitiveVariable( new CqParameterTypedVarying( "s", new EqVariableType( type_float ), p_float.class, p_float.class ));
	        s().SetSize( 4 );
	        for ( int i = 0; i < 4; i++ )
	        	((p_float)( s().pValue_get(0 , i ))).value = m_pAttributes.GetFloatAttribute( "System", "TextureCoordinates" ) [ i * 2 ];
	    }

	    if ( USES( bUses, EnvVars_t ) && bUseDef_st && !bHasVar(EnvVars_t))
	    {
	        AddPrimitiveVariable( new CqParameterTypedVarying( "t", new EqVariableType( type_float ), p_float.class, p_float.class ));
	        t().SetSize( 4 );
	        for ( int i = 0; i < 4; i++ )
	        	((p_float)( t().pValue_get(0 , i ))).value = m_pAttributes.GetFloatAttribute( "System", "TextureCoordinates" ) [ ( i * 2 ) + 1 ];
	    }

	    if ( USES( bUses, EnvVars_u ) )
	    {
	        AddPrimitiveVariable( new CqParameterTypedVarying( "u", new EqVariableType( type_float ), p_float.class, p_float.class ));
	        u().SetSize( 4 );
	        
	        ((p_float)( u().pValue_get(0 , 0 ))).value = 0.0f;
	        ((p_float)( u().pValue_get(0 , 2 ))).value = 0.0f;
	        ((p_float)( u().pValue_get(0 , 1 ))).value = 1.0f;
	        ((p_float)( u().pValue_get(0 , 3 ))).value = 1.0f;
	        
	    }

	    if ( USES( bUses, EnvVars_v ) )
	    {
	        AddPrimitiveVariable( new CqParameterTypedVarying( "v", new EqVariableType( type_float ), p_float.class, p_float.class ));
	        v().SetSize( 4 );
	        ((p_float)( v().pValue_get(0 , 0 ))).value = 0.0f;
	        ((p_float)( v().pValue_get(0 , 1 ))).value = 0.0f;
	        ((p_float)( v().pValue_get(0 , 2 ))).value = 1.0f;
	        ((p_float)( v().pValue_get(0 , 3 ))).value = 1.0f;
	    }
	}
	
	
	/**
	 * 
	 * Copy all the primitive variables from the donor to this.
	 * 全てをコピーする。
	 * 
	 * @param From	コピー元
	 */
	public void ClonePrimitiveVariables( final CqSurface From )
	{
	    // Clone any primitive variables.
	    m_aUserParams.clear();
	    for ( CqParameter iUP : From.m_aUserParams ){
	        AddPrimitiveVariable( iUP.Clone() );
	    }

	    // Copy the standard primitive variables index table.
	    for ( int i = 0; i < EnvVars_Last; i++ ){
	        m_aiStdPrimitiveVars[ i ] = From.m_aiStdPrimitiveVars[ i ];
	    }
	}
	
	
    /**
     *  Get a reference the to P default parameter.<br>
     *  Pのデフォルト値の参照を得る。
     * 
     * @return	Pの参照、またはnull
     */
    @SuppressWarnings("unchecked")
	public CqParameterTyped<CqVector4D, CqVector3D> P()
    {
        if ( m_aiStdPrimitiveVars[ EnvVars_P ] >= 0 )
            return ( (CqParameterTyped<CqVector4D, CqVector3D>)( m_aUserParams.get( m_aiStdPrimitiveVars[ EnvVars_P ] ) ) );
        else
            return ( null );
    }
    
    
    /**
     *  Get a reference the to N default parameter.<br>
     *  Nのデフォルト値の参照を得る。 
     * 
     * @return	Nの参照、またはnull
     */
    @SuppressWarnings("unchecked")
	public CqParameterTyped<CqVector3D, CqVector3D> N()
    {
        if ( m_aiStdPrimitiveVars[ EnvVars_N ] >= 0 )
            return ( (CqParameterTyped<CqVector3D, CqVector3D>)( m_aUserParams.get( m_aiStdPrimitiveVars[ EnvVars_N ] ) ) );
        else
            return ( null );
    }
    
    
    /**
     *  Get a reference the to Cq default parameter.<br>
     *  Cqのデフォルト値の参照を得る。
     * 
     * @return	Cqの参照、またはnull
     */
    @SuppressWarnings("unchecked")
	public CqParameterTyped<CqColor, CqColor> Cs()
    {
        if ( m_aiStdPrimitiveVars[ EnvVars_Cs ] >= 0 )
            return ( (CqParameterTyped<CqColor, CqColor>)( m_aUserParams.get( m_aiStdPrimitiveVars[ EnvVars_Cs ] ) ) );
        else
            return ( null );
    }
    
    
    /**
     *  Get a reference the to Os default parameter.<br>
     *  Osのデフォルト値の参照を得る。 
     * 
     * @return	Osの参照、またはnull
     */
    @SuppressWarnings("unchecked")
	public CqParameterTyped<CqColor, CqColor> Os()
    {
        if ( m_aiStdPrimitiveVars[ EnvVars_Os ] >= 0 )
            return ( (CqParameterTyped<CqColor, CqColor>)( m_aUserParams.get( m_aiStdPrimitiveVars[ EnvVars_Os ] ) ) );
        else
            return ( null );
    }
    
    
    /**
     *  Get a reference the to s default parameter.<br>
     *  sのデフォルト値の参照を得る。
     *  
     *  @return	sの参照、またはnull
     */
    @SuppressWarnings("unchecked")
	public CqParameterTyped<p_float, p_float> s()
    {
        if ( m_aiStdPrimitiveVars[ EnvVars_s ] >= 0 )
            return ( (CqParameterTyped<p_float, p_float>)( m_aUserParams.get( m_aiStdPrimitiveVars[ EnvVars_s ] ) ) );
        else
            return ( null );
    }
    
    
    /**
     *  Get a reference the to t default parameter.<br>
     *  tのデフォルト値の参照を得る。
     * 
     * @return	tの参照、またはnull
     */
    @SuppressWarnings("unchecked")
	public CqParameterTyped<p_float, p_float> t()
    {
        if ( m_aiStdPrimitiveVars[ EnvVars_t ] >= 0 )
            return ( (CqParameterTyped<p_float, p_float>)( m_aUserParams.get( m_aiStdPrimitiveVars[ EnvVars_t ] ) ) );
        else
            return ( null );
    }
    
    
    /**
     *  Get a reference the to u default parameter.<br>
     *  uのデフォルト値の参照を得る。
     *  
     *  @return	uの参照、またはnull
     */
    @SuppressWarnings("unchecked")
	public CqParameterTyped<p_float, p_float> u()
    {
        if ( m_aiStdPrimitiveVars[ EnvVars_u ] >= 0 )
            return ( (CqParameterTyped<p_float, p_float>)( m_aUserParams.get( m_aiStdPrimitiveVars[ EnvVars_u ] ) ) );
        else
            return ( null );
    }
    
    
    /**
     *  Get a reference the to v default parameter.<br>
     *  vのテフォルトの値の参照を得る。
     * 
     * @return	vの参照、またはnull
     */
    @SuppressWarnings("unchecked")
	public CqParameterTyped<p_float, p_float> v()
    {
        if ( m_aiStdPrimitiveVars[ EnvVars_v ] >= 0 )
            return ( (CqParameterTyped<p_float, p_float>)( m_aUserParams.get( m_aiStdPrimitiveVars[ EnvVars_v ] ) ) );
        else
            return ( null );
    } 
	
    
    /**
     *  Get a reference the to an indexed primitive variable. <br>
     *  与えられたインデックスが示す参照を返す。
     * 
     * @param index	インデックス
     * @return	インデックスが示す参照、またはnull
     */
    public CqParameter pVar(int index)
    {
        assert( index >= EnvVars_Cs && index < EnvVars_Last );
        if ( m_aiStdPrimitiveVars[ index ] >= 0 )
            return ( m_aUserParams.get( m_aiStdPrimitiveVars[ index ] ) );
        else
            return ( null );
    }

    
    /**
     * Determine whether this surface has <br>
     * a specified primitive variable based on index <br>
     * 自分自身が、与えられたインデックスの示す参照を持つかどうかの判定を返す。
     * 
     * @param index	インデックス
     * @return	true/false
     */
    public boolean bHasVar(int index)
    {
        assert( index >= EnvVars_Cs && index < EnvVars_Last );
        // Special case for s & t if "st" is specified.
        if( index == EnvVars_s || index == EnvVars_t )
            return( m_aiStdPrimitiveVars[ index ] >= 0 || FindUserParam("st")!=null );
        else
            return ( m_aiStdPrimitiveVars[ index ] >= 0 );
    }
    
    
    /**
     *  Get a reference to the user parameter variables array<br>
     *  使用するパラメータをもつ配列を取得。
     * 
     * @return	m_aUserParams
     */
    public STLVector<CqParameter> aUserParams()
    {
        return ( m_aUserParams );
    }

    
    /**
     *  Find out if a named user parameter exists on this surface.<br>
     * 　与えれた名前に対応するパラメータが存在する場合、そのパラメータを返す。
     *  
     * @param name	パラメータ名。
     * @return	名前に対応するパラメータ。
     */
    public CqParameter FindUserParam( final String name )
    {
    	long strName = name.hashCode();
    	
    	for( CqParameter iUP : m_aUserParams )
    	{
    		if( iUP.hash() == strName )
    			return iUP;
    	}
    	
    	return( null );
    }

    
    /**
     *  Add a primitive variable to the array.
     *  パラメータ配列に値を追加する。
     * 
     * @param pParam	追加するパラメータ。
     */
    public void AddPrimitiveVariable( CqParameter pParam )
    {
    	m_aUserParams.add( pParam );
    	
    	if ( pParam.hash() == RIH_P )
    	{
    		assert( -1 == m_aiStdPrimitiveVars[ EnvVars_P ] );
    		m_aiStdPrimitiveVars[ EnvVars_P ] = m_aUserParams.size() - 1;
    	}
    	else if ( pParam.hash() == RIH_N )
    	{
    		assert( -1 == m_aiStdPrimitiveVars[ EnvVars_N ] );
    		m_aiStdPrimitiveVars[ EnvVars_N ] = m_aUserParams.size() - 1;
    	}
    	
    	else if ( pParam.hash() == RIH_CS )
    	{
    		assert( -1 == m_aiStdPrimitiveVars[ EnvVars_Cs ] );
    		m_aiStdPrimitiveVars[ EnvVars_Cs ] = m_aUserParams.size() - 1;
    	}
    	else if ( pParam.hash() == RIH_OS )
    	{
    		assert( -1 == m_aiStdPrimitiveVars[ EnvVars_Os ] );
    		m_aiStdPrimitiveVars[ EnvVars_Os ] = m_aUserParams.size() - 1;
    	}
    	else if ( pParam.hash() == RIH_S  )
    	{
    		assert( -1 == m_aiStdPrimitiveVars[ EnvVars_s ] );
    		m_aiStdPrimitiveVars[ EnvVars_s ] = m_aUserParams.size() - 1;
    	}
    	else if ( pParam.hash() == RIH_T)
    	{
    		assert( -1 == m_aiStdPrimitiveVars[ EnvVars_t ] );
    		m_aiStdPrimitiveVars[ EnvVars_t ] = m_aUserParams.size() - 1;
    	}
    	else if ( pParam.hash() == RIH_U)
    	{
    		assert( -1 == m_aiStdPrimitiveVars[ EnvVars_u ] );
    		m_aiStdPrimitiveVars[ EnvVars_u ] = m_aUserParams.size() - 1;
    	}
    	else if ( pParam.hash() == RIH_V )
    	{
    		assert( -1 == m_aiStdPrimitiveVars[ EnvVars_v ] );
    		m_aiStdPrimitiveVars[ EnvVars_v ] = m_aUserParams.size() - 1;
    	}
    }
    
    
    /**
     *  Determine whether this surface can be trimmed
     *　　表面を切り取れるかどうかを判定する。 
     * 
     * @return	false
     */
    public boolean bCanBeTrimmed()
    {
        return ( false );
    }
    
    
    /**
     *  Determine if the specified point is trimmed.
     * 　指定されたポイントを切り取れるかどうかを判定する。
     * 
     * @param p	切り取るポイント
     * @return	false
     */
    public	boolean bIsPointTrimmed( final CqVector2D p )
    {
        return ( false );
    }
    
    
    /**
     *  Determine if the specified edge crosses the trimming curves.
     *  指定されたエッジがトリムカーブに交差しているかどうかを判定する。
     * 
     * @param v1	エッジを示すポイント
     * @param v2	エッジを示すポイント(もう片方)
     * @return	false
     */
    public	boolean bIsLineIntersecting( final CqVector2D v1, final CqVector2D v2 )
    {
        return ( false );
    }
    
    
    /**
     * Determine the level at which to split a trim curve according
     * to its screen size after application to the surface paramters of this
     * surface.
     * 
     * 
     * @param Curve
     * @return
     */
    public	int TrimDecimation( final CqTrimCurve Curve )
    {
        return ( 0 );
    }
    
    /** Prepare the trim curve once the surface has been completed.
     */
    /* (non-Javadoc)
     * @see net.cellcomputing.himawari.library.CqBasicSurface#PrepareTrimCurve()
     */
    public 	void PrepareTrimCurve()
    {}
    
    /** uSubdivide any user defined parameter variables.
     */
    public void uSubdivideUserParameters( CqSurface pA, CqSurface pB )
    {
        // Iterate through any use parameters subdividing and storing the second value in the target surface.
    	for( CqParameter iUP : m_aUserParams )
        {
            CqParameter pNewA = iUP.Clone();
            CqParameter pNewB = iUP.Clone();
            iUP.Subdivide( pNewA, pNewB, true, this );
            pA.AddPrimitiveVariable( pNewA );
            pB.AddPrimitiveVariable( pNewB );
        }
    }
    
    /** vSubdivide any user defined parameter variables.
     */
    public void vSubdivideUserParameters( CqSurface pA, CqSurface pB )
    {
        // Iterate through any use parameters subdividing and storing the second value in the target surface.
    	for( CqParameter iUP : m_aUserParams )
        {
            CqParameter pNewA = iUP.Clone();
            CqParameter pNewB = iUP.Clone();
            iUP.Subdivide( pNewA, pNewB, false, this );
            pA.AddPrimitiveVariable( pNewA );
            pB.AddPrimitiveVariable( pNewB );
        }
    }
    
    
    /**
     *  Virtual function to indicate whether a particular surface is able
     *  to generate geometric normals itself.
     * 
     * 
     * @return
     */
    public boolean CanGenerateNormals()
    {
        return ( false );
    }
    

    
    /**
     * Virtual function to genrate and fill in geomtric normals if a surface is able to do so.
     * 
     * 
     * @param uDiceSize
     * @param vDiceSize
     * @param pNormals
     */
    public	void GenerateGeometricNormals( int uDiceSize, int vDiceSize, IqShaderData pNormals )
    {}
    


	//************************************************************************//
	//*** テンプレートの実装
	//************************************************************************//
    
    /**
     * 
     * 
     * 
     * @param <T>
     * @param <SLT>
     * @param uSize
     * @param vSize
     * @param pParam
     * @param pData
     */
    //nttdata 高速化
//    protected <T, SLT> void TypedNaturalDice( float uSize, float vSize, CqParameterTyped<T, SLT> pParam, IqShaderData pData )
//    {
//        int iv, iu;
//        Class TClass = pParam.TClass;
//        Class SLTClass = pParam.SLTClass;
//        
//        for ( iv = 0; iv <= vSize; iv++ )
//        {
//            float v = ( 1.0f / vSize ) * iv;
//            for ( iu = 0; iu <= uSize; iu++ )
//            {
//            	float u = ( 1.0f / uSize ) * iu;
//            	//型による判別を行う。
//            	//CqVector3DがGenericsに指定された場合
//            	if( TClass.equals( CqVector3D.class ) && SLTClass.equals( CqVector3D.class ) )
//            	{
//            		Object vec = BilinearEvaluate( pParam.pValue() [ 0 ], pParam.pValue() [ 1 ], pParam.pValue() [ 2 ], pParam.pValue() [ 3 ], u, v, CqVector3D.class );
//                    int igrid = (int)( ( iv * ( uSize + 1 ) ) + iu );
//                    pData.SetValue( (CqVector3D)vec, igrid );
//            	}
//            	//CqVector4D,CqVector3DがGenericsに指定された場合
//            	else if( TClass.equals( CqVector4D.class ) && SLTClass.equals( CqVector3D.class ) )
//            	{
//            		Object vec = BilinearEvaluate( pParam.pValue() [ 0 ], pParam.pValue() [ 1 ], pParam.pValue() [ 2 ], pParam.pValue() [ 3 ], u, v, CqVector4D.class );
//                    int igrid = (int)( ( iv * ( uSize + 1 ) ) + iu );
//                    pData.SetValue( new CqVector3D((CqVector4D)vec), igrid );
//            	}
//            	//CqColorがGenericsに指定された場合
//            	else if( TClass.equals( CqColor.class ) && SLTClass.equals( CqColor.class ) )
//            	{
//            		Object vec = BilinearEvaluate( pParam.pValue() [ 0 ], pParam.pValue() [ 1 ], pParam.pValue() [ 2 ], pParam.pValue() [ 3 ], u, v, CqColor.class );
//                    int igrid = (int)( ( iv * ( uSize + 1 ) ) + iu );
//                    pData.SetValue( (CqColor)vec, igrid );
//            	}
//            	//CqMatrixがGenericsに指定された場合
//            	else if( TClass.equals( CqMatrix.class ) && SLTClass.equals( CqMatrix.class ) )
//            	{
//            		Object vec = BilinearEvaluate( pParam.pValue() [ 0 ], pParam.pValue() [ 1 ], pParam.pValue() [ 2 ], pParam.pValue() [ 3 ], u, v, CqMatrix.class );
//                    int igrid = (int)( ( iv * ( uSize + 1 ) ) + iu );
//                    pData.SetValue( (CqMatrix)vec, igrid );
//            	}
//            	//p_int,p_intがGenericsに指定された場合
//            	else if( TClass.equals( p_int.class ) && SLTClass.equals( p_int.class ) )
//            	{
//            		Object vec = BilinearEvaluate( pParam.pValue() [ 0 ], pParam.pValue() [ 1 ], pParam.pValue() [ 2 ], pParam.pValue() [ 3 ], u, v, p_int.class );
//                    int igrid = (int)( ( iv * ( uSize + 1 ) ) + iu );
//                    pData.SetValue( ((p_int)vec).value, igrid );
//            	}
//            	//p_floatがGenericsに指定された場合
//            	else if( TClass.equals( p_float.class ) && SLTClass.equals( p_float.class ) )
//            	{
//            		Object vec = BilinearEvaluate( pParam.pValue() [ 0 ], pParam.pValue() [ 1 ], pParam.pValue() [ 2 ], pParam.pValue() [ 3 ], u, v, p_float.class );
//                    int igrid = (int)( ( iv * ( uSize + 1 ) ) + iu );
//                    pData.SetValue( ((p_float)vec).value, igrid );
//            	}
//            	//p_int,p_floatがGenericsに指定された場合
//            	else if( TClass.equals( p_int.class ) && SLTClass.equals( p_float.class ) )
//            	{
//            		Object vec = BilinearEvaluate( pParam.pValue() [ 0 ], pParam.pValue() [ 1 ], pParam.pValue() [ 2 ], pParam.pValue() [ 3 ], u, v, p_int.class );
//                    int igrid = (int)( ( iv * ( uSize + 1 ) ) + iu );
//                    pData.SetValue( ((p_int)vec).value, igrid );
//            	}
//            	else{ //　想定しない TClass と SLTClass の組み合わせ 	
//            	}
//            }
//        }
//    }
    protected <T, SLT> void TypedNaturalDice( float uSize, float vSize, CqParameterTyped<T, SLT> pParam, IqShaderData pData )
    {
        int iv, iu;
        Class TClass = pParam.TClass;
        Class SLTClass = pParam.SLTClass;
        
        for ( iv = 0; iv <= vSize; iv++ )
        {
            float v = ( 1.0f / vSize ) * iv;
            for ( iu = 0; iu <= uSize; iu++ )
            {
            	float u = ( 1.0f / uSize ) * iu;
            	//型による判別を行う。
            	//CqVector3DがGenericsに指定された場合
            	if( TClass.equals( CqVector3D.class ) && SLTClass.equals( CqVector3D.class ) )
            	{
            		Object vec = BilinearEvaluate( pParam.pValue_get(0 , 0 ), pParam.pValue_get(0 , 1 ), pParam.pValue_get(0 , 2 ), pParam.pValue_get(0 , 3 ), u, v, CqVector3D.class );
                    int igrid = (int)( ( iv * ( uSize + 1 ) ) + iu );
                    pData.SetValue( (CqVector3D)vec, igrid );
            	}
            	//CqVector4D,CqVector3DがGenericsに指定された場合
            	else if( TClass.equals( CqVector4D.class ) && SLTClass.equals( CqVector3D.class ) )
            	{
            		Object vec = BilinearEvaluate( pParam.pValue_get(0 , 0 ), pParam.pValue_get(0 , 1 ), pParam.pValue_get(0 , 2 ), pParam.pValue_get(0 , 3 ), u, v, CqVector4D.class );
                    int igrid = (int)( ( iv * ( uSize + 1 ) ) + iu );
                    pData.SetValue( new CqVector3D((CqVector4D)vec), igrid );
            	}
            	//CqColorがGenericsに指定された場合
            	else if( TClass.equals( CqColor.class ) && SLTClass.equals( CqColor.class ) )
            	{
            		Object vec = BilinearEvaluate( pParam.pValue_get(0 , 0 ), pParam.pValue_get(0 , 1 ), pParam.pValue_get(0 , 2 ), pParam.pValue_get(0 , 3 ), u, v, CqColor.class );
                    int igrid = (int)( ( iv * ( uSize + 1 ) ) + iu );
                    pData.SetValue( (CqColor)vec, igrid );
            	}
            	//CqMatrixがGenericsに指定された場合
            	else if( TClass.equals( CqMatrix.class ) && SLTClass.equals( CqMatrix.class ) )
            	{
            		Object vec = BilinearEvaluate( pParam.pValue_get(0 , 0 ), pParam.pValue_get(0 , 1 ), pParam.pValue_get(0 , 2 ), pParam.pValue_get(0 , 3 ), u, v, CqMatrix.class );
                    int igrid = (int)( ( iv * ( uSize + 1 ) ) + iu );
                    pData.SetValue( (CqMatrix)vec, igrid );
            	}
            	//p_int,p_intがGenericsに指定された場合
            	else if( TClass.equals( p_int.class ) && SLTClass.equals( p_int.class ) )
            	{
            		Object vec = BilinearEvaluate( pParam.pValue_get(0 , 0 ), pParam.pValue_get(0 , 1 ), pParam.pValue_get(0 , 2 ), pParam.pValue_get(0 , 3 ), u, v, p_int.class );
                    int igrid = (int)( ( iv * ( uSize + 1 ) ) + iu );
                    pData.SetValue( ((p_int)vec).value, igrid );
            	}
            	//p_floatがGenericsに指定された場合
            	else if( TClass.equals( p_float.class ) && SLTClass.equals( p_float.class ) )
            	{
            		Object vec = BilinearEvaluate( pParam.pValue_get(0 , 0 ), pParam.pValue_get(0 , 1 ), pParam.pValue_get(0 , 2 ), pParam.pValue_get(0 , 3 ), u, v, p_float.class );
                    int igrid = (int)( ( iv * ( uSize + 1 ) ) + iu );
                    pData.SetValue( ((p_float)vec).value, igrid );
            	}
            	//p_int,p_floatがGenericsに指定された場合
            	else if( TClass.equals( p_int.class ) && SLTClass.equals( p_float.class ) )
            	{
            		Object vec = BilinearEvaluate( pParam.pValue_get(0 , 0 ), pParam.pValue_get(0 , 1 ), pParam.pValue_get(0 , 2 ), pParam.pValue_get(0 , 3 ), u, v, p_int.class );
                    int igrid = (int)( ( iv * ( uSize + 1 ) ) + iu );
                    pData.SetValue( ((p_int)vec).value, igrid );
            	}
            	else{ //　想定しない TClass と SLTClass の組み合わせ 	
            	}
            }
        }
    }
    
    /**
     * 
     * 
     * 
     * @param <T>
     * @param <SLT>
     * @param pParam
     * @param pResult1
     * @param pResult2
     * @param u
     */
    //nttdata 高速化
//    protected <T, SLT> void TypedNaturalSubdivide( CqParameterTyped<T, SLT> pParam, CqParameterTyped<T, SLT> pResult1, CqParameterTyped<T, SLT> pResult2, boolean u )
//    {
//        CqParameterTyped<T, SLT> pTParam = (CqParameterTyped<T, SLT>)( pParam );
//        CqParameterTyped<T, SLT> pTResult1 = (CqParameterTyped<T, SLT>)( pResult1 );
//        CqParameterTyped<T, SLT> pTResult2 = (CqParameterTyped<T, SLT>)( pResult2 );
//        
//        if ( u )
//        {
//        	T t = (T)pTResult1.pValue(1)[0];
//        	//型の判別を行う。
//        	//インスタンスがp_floatのとき
//        	if( t instanceof p_float )
//        	{
//        		((p_float)pTResult2.pValue( 1 ) [ 0 ]).value = ((p_float)pTParam.pValue( 1 ) [ 0 ]).value;
//        		((p_float)pTResult2.pValue( 3 ) [ 0 ]).value = ((p_float)pTParam.pValue( 3 ) [ 0 ]).value;
//        		((p_float)pTResult1.pValue( 1 ) [ 0 ]).value = ((p_float)pTResult2.pValue( 0 ) [ 0 ]).value = (float)(( ((p_float)pTParam.pValue( 0 ) [ 0 ]).value + ((p_float)pTParam.pValue( 1 ) [ 0 ] ).value ) * 0.5f ); 
//        		((p_float)pTResult1.pValue( 3 ) [ 0 ]).value = ((p_float)pTResult2.pValue( 2 ) [ 0 ]).value = (float)(( ((p_float)pTParam.pValue( 2 ) [ 0 ]).value + ((p_float)pTParam.pValue( 3 ) [ 0 ] ).value ) * 0.5f );
//        	}//インスタンスがp_intのとき
//        	else if( t instanceof p_int )
//        	{
//        		((p_int)pTResult2.pValue( 1 ) [ 0 ]).value = ((p_int)pTParam.pValue( 1 ) [ 0 ]).value;
//        		((p_int)pTResult2.pValue( 3 ) [ 0 ]).value = ((p_int)pTParam.pValue( 3 ) [ 0 ]).value;
//        		((p_int)pTResult1.pValue( 1 ) [ 0 ]).value = ((p_int)pTResult2.pValue( 0 ) [ 0 ]).value = (int)((( (p_int)(pTParam.pValue( 0 ) [ 0 ])).value + ((p_int)(pTParam.pValue( 1 ) [ 0 ])).value ) * 0.5f);
//        		((p_int)pTResult1.pValue( 3 ) [ 0 ]).value = ((p_int)pTResult2.pValue( 2 ) [ 0 ]).value = (int)((( (p_int)(pTParam.pValue( 2 ) [ 0 ])).value + ((p_int)(pTParam.pValue( 3 ) [ 0 ])).value ) * 0.5f);
//        	}//インスタンスがp_Stringのとき
//        	else if( t instanceof p_String )
//        	{
//        		((p_String)pTResult2.pValue( 1 ) [ 0 ]).value = ((p_String)pTParam.pValue( 1 ) [ 0 ]).value;
//        		((p_String)pTResult2.pValue( 3 ) [ 0 ]).value = ((p_String)pTParam.pValue( 3 ) [ 0 ]).value;
//        		((p_String)pTResult1.pValue( 1 ) [ 0 ]).value = ((p_String)pTResult2.pValue( 0 ) [ 0 ]).value = (String)((( (p_String)(pTParam.pValue( 0 ) [ 0 ])).value) + ((p_String)(pTParam.pValue( 1 ) [ 0 ])).value );
//        		((p_String)pTResult1.pValue( 3 ) [ 0 ]).value = ((p_String)pTResult2.pValue( 2 ) [ 0 ]).value = (String)((( (p_String)(pTParam.pValue( 2 ) [ 0 ])).value) + ((p_String)(pTParam.pValue( 3 ) [ 0 ])).value );
//        	}//インスタンスがCqMatrixのとき
//        	else if( t instanceof CqMatrix )
//        	{
//        		((CqMatrix)pTResult2.pValue( 1 ) [ 0 ]).assignment((CqMatrix)pTParam.pValue( 1 ) [ 0 ]);
//        		((CqMatrix)pTResult2.pValue( 3 ) [ 0 ]).assignment((CqMatrix)pTParam.pValue( 3 ) [ 0 ]);
//        		((CqMatrix)pTResult1.pValue( 1 ) [ 0 ]).assignment(((CqMatrix)pTResult2.pValue( 0 ) [ 0 ]).assignment((((CqMatrix)(pTParam.pValue( 0 ) [ 0 ])).add(((CqMatrix)(pTParam.pValue( 1 ) [ 0 ])) )).multiply(0.5f)));
//        		((CqMatrix)pTResult1.pValue( 3 ) [ 0 ]).assignment(((CqMatrix)pTResult2.pValue( 2 ) [ 0 ]).assignment((((CqMatrix)(pTParam.pValue( 2 ) [ 0 ])).add(((CqMatrix)(pTParam.pValue( 3 ) [ 0 ])) )).multiply(0.5f)));	                		                	
//        		
//        	}//インスタンスがCqColorのとき
//        	else if( t instanceof CqColor )
//        	{
//        		((CqColor)pTResult2.pValue( 1 ) [ 0 ]).assignment(((CqColor)pTParam.pValue( 1 ) [ 0 ]));
//        		((CqColor)pTResult2.pValue( 3 ) [ 0 ]).assignment(((CqColor)pTParam.pValue( 3 ) [ 0 ]));
//        		((CqColor)pTResult1.pValue( 1 ) [ 0 ]).assignment((((CqColor)pTResult2.pValue( 0 ) [ 0 ]).assignment(((((CqColor)(pTParam.pValue( 0 ) [ 0 ])).add((CqColor)(pTParam.pValue( 1 ) [ 0 ]))).mul(0.5f)))));
//        		((CqColor)pTResult1.pValue( 3 ) [ 0 ]).assignment((((CqColor)pTResult2.pValue( 2 ) [ 0 ]).assignment(((((CqColor)(pTParam.pValue( 2 ) [ 0 ])).add((CqColor)(pTParam.pValue( 3 ) [ 0 ]))).mul(0.5f)))));	                		                	
//        		
//        	}//インスタンスがCqVector3Dのとき
//        	else if( t instanceof CqVector3D )
//        	{
//        		((CqVector3D)pTResult2.pValue( 1 ) [ 0 ]).assignment((CqVector3D)pTParam.pValue( 1 ) [ 0 ]);
//        		((CqVector3D)pTResult2.pValue( 3 ) [ 0 ]).assignment((CqVector3D)pTParam.pValue( 3 ) [ 0 ]);
//        		((CqVector3D)pTResult1.pValue( 1 ) [ 0 ]).assignment(((CqVector3D)pTResult2.pValue( 0 ) [ 0 ]).assignment((((CqVector3D)(pTParam.pValue( 0 ) [ 0 ])).add(((CqVector3D)(pTParam.pValue( 1 ) [ 0 ])) )).mul(0.5f)));
//        		((CqVector3D)pTResult1.pValue( 3 ) [ 0 ]).assignment(((CqVector3D)pTResult2.pValue( 2 ) [ 0 ]).assignment((((CqVector3D)(pTParam.pValue( 2 ) [ 0 ])).add(((CqVector3D)(pTParam.pValue( 3 ) [ 0 ])) )).mul(0.5f)));	                		                	
//        		
//        	}//インスタンスがCqVector4Dのとき
//        	else if( t instanceof CqVector4D )
//        	{
//        		((CqVector4D)pTResult2.pValue( 1 ) [ 0 ]).assignment((CqVector4D)pTParam.pValue( 1 ) [ 0 ]);
//        		((CqVector4D)pTResult2.pValue( 3 ) [ 0 ]).assignment((CqVector4D)pTParam.pValue( 3 ) [ 0 ]);
//        		((CqVector4D)pTResult1.pValue( 1 ) [ 0 ]).assignment(((CqVector4D)pTResult2.pValue( 0 ) [ 0 ]).assignment((((CqVector4D)(pTParam.pValue( 0 ) [ 0 ])).add(((CqVector4D)(pTParam.pValue( 1 ) [ 0 ])) )).mul(0.5f)));
//        		((CqVector4D)pTResult1.pValue( 3 ) [ 0 ]).assignment(((CqVector4D)pTResult2.pValue( 2 ) [ 0 ]).assignment((((CqVector4D)(pTParam.pValue( 2 ) [ 0 ])).add(((CqVector4D)(pTParam.pValue( 3 ) [ 0 ])) )).mul(0.5f)));	                		                	
//        		
//        	}
//        	else{ //想定しないインスタンスの型。
//        	}
//        }
//        else
//        {
//        	T t = (T)pTResult1.pValue(1)[0];
//        	//型の判別を行う。
//        	//インスタンスがp_floatのとき
//        	if( t instanceof p_float)
//        	{
//        		((p_float)pTResult2.pValue( 2 ) [ 0 ]).value = ((p_float)pTParam.pValue( 2 ) [ 0 ]).value;
//        		((p_float)pTResult2.pValue( 3 ) [ 0 ]).value = ((p_float)pTParam.pValue( 3 ) [ 0 ]).value;
//        		((p_float)pTResult1.pValue( 2 ) [ 0 ]).value = ((p_float)pTResult2.pValue( 0 ) [ 0 ]).value = (float)(( ((p_float)pTParam.pValue( 0 ) [ 0 ]).value + ((p_float)pTParam.pValue( 2 ) [ 0 ]).value ) * 0.5 );
//        		((p_float)pTResult1.pValue( 3 ) [ 0 ]).value = ((p_float)pTResult2.pValue( 1 ) [ 0 ]).value = (float)(( ((p_float)pTParam.pValue( 1 ) [ 0 ]).value + ((p_float)pTParam.pValue( 3 ) [ 0 ]).value ) * 0.5 );
//        	}//インスタンスがp_intのとき
//        	else if(t instanceof p_int)
//        	{
//        		((p_int)pTResult2.pValue( 2 ) [ 0 ]).value = ((p_int)pParam.pValue( 2 ) [ 0 ]).value;
//        		((p_int)pTResult2.pValue( 3 ) [ 0 ]).value = ((p_int)pParam.pValue( 3 ) [ 0 ]).value;
//        		((p_int)pTResult1.pValue( 2 ) [ 0 ]).value = ((p_int)pTResult2.pValue( 0 ) [ 0 ]).value = (int)((( (p_int)(pParam.pValue( 0 ) [ 0 ])).value + ((p_int)(pParam.pValue( 2 ) [ 0 ])).value ) * 0.5f);
//        		((p_int)pTResult1.pValue( 3 ) [ 0 ]).value = ((p_int)pTResult2.pValue( 1 ) [ 0 ]).value = (int)((( (p_int)(pParam.pValue( 1 ) [ 0 ])).value + ((p_int)(pParam.pValue( 3 ) [ 0 ])).value ) * 0.5f);
//        	}//インスタンスがp_intのとき
//        	else if(t instanceof p_String)
//        	{
//        		((p_String)pTResult2.pValue( 2 ) [ 0 ]).value = ((p_String)pParam.pValue( 2 ) [ 0 ]).value;
//        		((p_String)pTResult2.pValue( 3 ) [ 0 ]).value = ((p_String)pParam.pValue( 3 ) [ 0 ]).value;
//        		((p_String)pTResult1.pValue( 2 ) [ 0 ]).value = ((p_String)pTResult2.pValue( 0 ) [ 0 ]).value = (String)((( (p_String)(pParam.pValue( 0 ) [ 0 ])).value + ((p_String)(pParam.pValue( 2 ) [ 0 ])).value ));
//        		((p_String)pTResult1.pValue( 3 ) [ 0 ]).value = ((p_String)pTResult2.pValue( 1 ) [ 0 ]).value = (String)((( (p_String)(pParam.pValue( 1 ) [ 0 ])).value + ((p_String)(pParam.pValue( 3 ) [ 0 ])).value ));
//        	}//インスタンスがCqMatrixtのとき
//        	else if(t instanceof CqMatrix)
//        	{
//        		((CqMatrix)pTResult2.pValue( 2 ) [ 0 ]).assignment((CqMatrix)pParam.pValue( 2 ) [ 0 ]);
//        		((CqMatrix)pTResult2.pValue( 3 ) [ 0 ]).assignment((CqMatrix)pParam.pValue( 3 ) [ 0 ]);
//        		((CqMatrix)pTResult1.pValue( 2 ) [ 0 ]).assignment(((CqMatrix)pTResult2.pValue( 0 ) [ 0 ]).assignment((((CqMatrix)(pParam.pValue( 0 ) [ 0 ])).add(((CqMatrix)(pParam.pValue( 2 ) [ 0 ])) )).multiply(0.5f)));
//        		((CqMatrix)pTResult1.pValue( 3 ) [ 0 ]).assignment(((CqMatrix)pTResult2.pValue( 1 ) [ 0 ]).assignment((((CqMatrix)(pParam.pValue( 1 ) [ 0 ])).add(((CqMatrix)(pParam.pValue( 3 ) [ 0 ])) )).multiply(0.5f)));	                		                	
//        	}//インスタンスがCqColorのとき
//        	else if(t instanceof CqColor)
//        	{
//        		((CqColor)pTResult2.pValue( 2 ) [ 0 ]).assignment(((CqColor)pParam.pValue( 2 ) [ 0 ]));
//        		((CqColor)pTResult2.pValue( 3 ) [ 0 ]).assignment(((CqColor)pParam.pValue( 3 ) [ 0 ]));
//        		((CqColor)pTResult1.pValue( 2 ) [ 0 ]).assignment((((CqColor)pTResult2.pValue( 0 ) [ 0 ]).assignment(((((CqColor)(pParam.pValue( 0 ) [ 0 ])).add((CqColor)(pParam.pValue( 2 ) [ 0 ]))).mul(0.5f)))));
//        		((CqColor)pTResult1.pValue( 3 ) [ 0 ]).assignment((((CqColor)pTResult2.pValue( 1 ) [ 0 ]).assignment(((((CqColor)(pParam.pValue( 1 ) [ 0 ])).add((CqColor)(pParam.pValue( 3 ) [ 0 ]))).mul(0.5f)))));	                		                	
//        		
//        	}//インスタンスがCqVector3Dのとき
//        	else if(t instanceof CqVector3D)
//        	{
//        		((CqVector3D)pTResult2.pValue( 2 ) [ 0 ]).assignment((CqVector3D)pParam.pValue( 2 ) [ 0 ]);
//        		((CqVector3D)pTResult2.pValue( 3 ) [ 0 ]).assignment((CqVector3D)pParam.pValue( 3 ) [ 0 ]);
//        		((CqVector3D)pTResult1.pValue( 2 ) [ 0 ]).assignment(((CqVector3D)pTResult2.pValue( 0 ) [ 0 ]).assignment((((CqVector3D)(pParam.pValue( 0 ) [ 0 ])).add(((CqVector3D)(pParam.pValue( 2 ) [ 0 ])) )).mul(0.5f)));
//        		((CqVector3D)pTResult1.pValue( 3 ) [ 0 ]).assignment(((CqVector3D)pTResult2.pValue( 1 ) [ 0 ]).assignment((((CqVector3D)(pParam.pValue( 1 ) [ 0 ])).add(((CqVector3D)(pParam.pValue( 3 ) [ 0 ])) )).mul(0.5f)));	                		                	
//        	}//インスタンスがCqVector4Dのとき
//        	else if(t instanceof CqVector4D)
//        	{
//        		((CqVector4D)pTResult2.pValue( 2 ) [ 0 ]).assignment((CqVector4D)pParam.pValue( 2 ) [ 0 ]);
//        		((CqVector4D)pTResult2.pValue( 3 ) [ 0 ]).assignment((CqVector4D)pParam.pValue( 3 ) [ 0 ]);
//        		((CqVector4D)pTResult1.pValue( 2 ) [ 0 ]).assignment(((CqVector4D)pTResult2.pValue( 0 ) [ 0 ]).assignment((((CqVector4D)(pParam.pValue( 0 ) [ 0 ])).add(((CqVector4D)(pParam.pValue( 2 ) [ 0 ])) )).mul(0.5f)));
//        		((CqVector4D)pTResult1.pValue( 3 ) [ 0 ]).assignment(((CqVector4D)pTResult2.pValue( 1 ) [ 0 ]).assignment((((CqVector4D)(pParam.pValue( 1 ) [ 0 ])).add(((CqVector4D)(pParam.pValue( 3 ) [ 0 ])) )).mul(0.5f)));	                		                	
//        	}else{ //　想定しないインスタンスの型。
//        	}
//        }
//    }
    protected <T, SLT> void TypedNaturalSubdivide( CqParameterTyped<T, SLT> pParam, CqParameterTyped<T, SLT> pResult1, CqParameterTyped<T, SLT> pResult2, boolean u )
    {
        CqParameterTyped<T, SLT> pTParam = (CqParameterTyped<T, SLT>)( pParam );
        CqParameterTyped<T, SLT> pTResult1 = (CqParameterTyped<T, SLT>)( pResult1 );
        CqParameterTyped<T, SLT> pTResult2 = (CqParameterTyped<T, SLT>)( pResult2 );
        
        if ( u )
        {
        	T t = (T)pTResult1.pValue_get(1,0);
        	//型の判別を行う。
        	//インスタンスがp_floatのとき
        	if( t instanceof p_float )
        	{
        		((p_float)pTResult2.pValue_get( 1 , 0 )).value = ((p_float)pTParam.pValue_get( 1 , 0 )).value;
        		((p_float)pTResult2.pValue_get( 3 , 0 )).value = ((p_float)pTParam.pValue_get( 3 , 0 )).value;
        		((p_float)pTResult1.pValue_get( 1 , 0 )).value = ((p_float)pTResult2.pValue_get( 0 , 0 )).value = (float)(( ((p_float)pTParam.pValue_get( 0 , 0 )).value + ((p_float)pTParam.pValue_get( 1 , 0 ) ).value ) * 0.5f ); 
        		((p_float)pTResult1.pValue_get( 3 , 0 )).value = ((p_float)pTResult2.pValue_get( 2 , 0 )).value = (float)(( ((p_float)pTParam.pValue_get( 2 , 0 )).value + ((p_float)pTParam.pValue_get( 3 , 0 ) ).value ) * 0.5f );
        	}//インスタンスがp_intのとき
        	else if( t instanceof p_int )
        	{
        		((p_int)pTResult2.pValue_get( 1 , 0 )).value = ((p_int)pTParam.pValue_get( 1 , 0 )).value;
        		((p_int)pTResult2.pValue_get( 3 , 0 )).value = ((p_int)pTParam.pValue_get( 3 , 0 )).value;
        		((p_int)pTResult1.pValue_get( 1 , 0 )).value = ((p_int)pTResult2.pValue_get( 0 , 0 )).value = (int)((( (p_int)(pTParam.pValue_get( 0 , 0 ))).value + ((p_int)(pTParam.pValue_get( 1 , 0 ))).value ) * 0.5f);
        		((p_int)pTResult1.pValue_get( 3 , 0 )).value = ((p_int)pTResult2.pValue_get( 2 , 0 )).value = (int)((( (p_int)(pTParam.pValue_get( 2 , 0 ))).value + ((p_int)(pTParam.pValue_get( 3 , 0 ))).value ) * 0.5f);
        	}//インスタンスがp_Stringのとき
        	else if( t instanceof p_String )
        	{
        		((p_String)pTResult2.pValue_get( 1 , 0 )).value = ((p_String)pTParam.pValue_get( 1 , 0 )).value;
        		((p_String)pTResult2.pValue_get( 3 , 0 )).value = ((p_String)pTParam.pValue_get( 3 , 0 )).value;
        		((p_String)pTResult1.pValue_get( 1 , 0 )).value = ((p_String)pTResult2.pValue_get( 0 , 0 )).value = (String)((( (p_String)(pTParam.pValue_get( 0 , 0 ))).value) + ((p_String)(pTParam.pValue_get( 1 , 0 ))).value );
        		((p_String)pTResult1.pValue_get( 3 , 0 )).value = ((p_String)pTResult2.pValue_get( 2 , 0 )).value = (String)((( (p_String)(pTParam.pValue_get( 2 , 0 ))).value) + ((p_String)(pTParam.pValue_get( 3 , 0 ))).value );
        	}//インスタンスがCqMatrixのとき
        	else if( t instanceof CqMatrix )
        	{
        		((CqMatrix)pTResult2.pValue_get( 1 , 0 )).assignment((CqMatrix)pTParam.pValue_get( 1 , 0 ));
        		((CqMatrix)pTResult2.pValue_get( 3 , 0 )).assignment((CqMatrix)pTParam.pValue_get( 3 , 0 ));
        		((CqMatrix)pTResult1.pValue_get( 1 , 0 )).assignment(((CqMatrix)pTResult2.pValue_get( 0 , 0 )).assignment((((CqMatrix)(pTParam.pValue_get( 0 , 0 ))).add(((CqMatrix)(pTParam.pValue_get( 1 , 0 ))) )).multiply(0.5f)));
        		((CqMatrix)pTResult1.pValue_get( 3 , 0 )).assignment(((CqMatrix)pTResult2.pValue_get( 2 , 0 )).assignment((((CqMatrix)(pTParam.pValue_get( 2 , 0 ))).add(((CqMatrix)(pTParam.pValue_get( 3 , 0 ))) )).multiply(0.5f)));	                		                	
        		
        	}//インスタンスがCqColorのとき
        	else if( t instanceof CqColor )
        	{
        		((CqColor)pTResult2.pValue_get( 1 , 0 )).assignment(((CqColor)pTParam.pValue_get( 1 , 0 )));
        		((CqColor)pTResult2.pValue_get( 3 , 0 )).assignment(((CqColor)pTParam.pValue_get( 3 , 0 )));
        		((CqColor)pTResult1.pValue_get( 1 , 0 )).assignment((((CqColor)pTResult2.pValue_get( 0 , 0 )).assignment(((((CqColor)(pTParam.pValue_get( 0 , 0 ))).add((CqColor)(pTParam.pValue_get( 1 , 0 )))).mul(0.5f)))));
        		((CqColor)pTResult1.pValue_get( 3 , 0 )).assignment((((CqColor)pTResult2.pValue_get( 2 , 0 )).assignment(((((CqColor)(pTParam.pValue_get( 2 , 0 ))).add((CqColor)(pTParam.pValue_get( 3 , 0 )))).mul(0.5f)))));	                		                	
        		
        	}//インスタンスがCqVector3Dのとき
        	else if( t instanceof CqVector3D )
        	{
        		((CqVector3D)pTResult2.pValue_get( 1 , 0 )).assignment((CqVector3D)pTParam.pValue_get( 1 , 0 ));
        		((CqVector3D)pTResult2.pValue_get( 3 , 0 )).assignment((CqVector3D)pTParam.pValue_get( 3 , 0 ));
        		((CqVector3D)pTResult1.pValue_get( 1 , 0 )).assignment(((CqVector3D)pTResult2.pValue_get( 0 , 0 )).assignment((((CqVector3D)(pTParam.pValue_get( 0 , 0 ))).add(((CqVector3D)(pTParam.pValue_get( 1 , 0 ))) )).mul(0.5f)));
        		((CqVector3D)pTResult1.pValue_get( 3 , 0 )).assignment(((CqVector3D)pTResult2.pValue_get( 2 , 0 )).assignment((((CqVector3D)(pTParam.pValue_get( 2 , 0 ))).add(((CqVector3D)(pTParam.pValue_get( 3 , 0 ))) )).mul(0.5f)));	                		                	
        		
        	}//インスタンスがCqVector4Dのとき
        	else if( t instanceof CqVector4D )
        	{
        		((CqVector4D)pTResult2.pValue_get( 1 , 0 )).assignment((CqVector4D)pTParam.pValue_get( 1 , 0 ));
        		((CqVector4D)pTResult2.pValue_get( 3 , 0 )).assignment((CqVector4D)pTParam.pValue_get( 3 , 0 ));
        		((CqVector4D)pTResult1.pValue_get( 1 , 0 )).assignment(((CqVector4D)pTResult2.pValue_get( 0 , 0 )).assignment((((CqVector4D)(pTParam.pValue_get( 0 , 0 ))).add(((CqVector4D)(pTParam.pValue_get( 1 , 0 ))) )).mul(0.5f)));
        		((CqVector4D)pTResult1.pValue_get( 3 , 0 )).assignment(((CqVector4D)pTResult2.pValue_get( 2 , 0 )).assignment((((CqVector4D)(pTParam.pValue_get( 2 , 0 ))).add(((CqVector4D)(pTParam.pValue_get( 3 , 0 ))) )).mul(0.5f)));	                		                	
        		
        	}
        	else{ //想定しないインスタンスの型。
        	}
        }
        else
        {
        	T t = (T)pTResult1.pValue_get(1,0);
        	//型の判別を行う。
        	//インスタンスがp_floatのとき
        	if( t instanceof p_float)
        	{
        		((p_float)pTResult2.pValue_get( 2 , 0 )).value = ((p_float)pTParam.pValue_get( 2 , 0 )).value;
        		((p_float)pTResult2.pValue_get( 3 , 0 )).value = ((p_float)pTParam.pValue_get( 3 , 0 )).value;
        		((p_float)pTResult1.pValue_get( 2 , 0 )).value = ((p_float)pTResult2.pValue_get( 0 , 0 )).value = (float)(( ((p_float)pTParam.pValue_get( 0 , 0 )).value + ((p_float)pTParam.pValue_get( 2 , 0 )).value ) * 0.5 );
        		((p_float)pTResult1.pValue_get( 3 , 0 )).value = ((p_float)pTResult2.pValue_get( 1 , 0 )).value = (float)(( ((p_float)pTParam.pValue_get( 1 , 0 )).value + ((p_float)pTParam.pValue_get( 3 , 0 )).value ) * 0.5 );
        	}//インスタンスがp_intのとき
        	else if(t instanceof p_int)
        	{
        		((p_int)pTResult2.pValue_get( 2 , 0 )).value = ((p_int)pParam.pValue_get( 2 , 0 )).value;
        		((p_int)pTResult2.pValue_get( 3 , 0 )).value = ((p_int)pParam.pValue_get( 3 , 0 )).value;
        		((p_int)pTResult1.pValue_get( 2 , 0 )).value = ((p_int)pTResult2.pValue_get( 0 , 0 )).value = (int)((( (p_int)(pParam.pValue_get( 0 , 0 ))).value + ((p_int)(pParam.pValue_get( 2 , 0 ))).value ) * 0.5f);
        		((p_int)pTResult1.pValue_get( 3 , 0 )).value = ((p_int)pTResult2.pValue_get( 1 , 0 )).value = (int)((( (p_int)(pParam.pValue_get( 1 , 0 ))).value + ((p_int)(pParam.pValue_get( 3 , 0 ))).value ) * 0.5f);
        	}//インスタンスがp_intのとき
        	else if(t instanceof p_String)
        	{
        		((p_String)pTResult2.pValue_get( 2 , 0 )).value = ((p_String)pParam.pValue_get( 2 , 0 )).value;
        		((p_String)pTResult2.pValue_get( 3 , 0 )).value = ((p_String)pParam.pValue_get( 3 , 0 )).value;
        		((p_String)pTResult1.pValue_get( 2 , 0 )).value = ((p_String)pTResult2.pValue_get( 0 , 0 )).value = (String)((( (p_String)(pParam.pValue_get( 0 , 0 ))).value + ((p_String)(pParam.pValue_get( 2 , 0 ))).value ));
        		((p_String)pTResult1.pValue_get( 3 , 0 )).value = ((p_String)pTResult2.pValue_get( 1 , 0 )).value = (String)((( (p_String)(pParam.pValue_get( 1 , 0 ))).value + ((p_String)(pParam.pValue_get( 3 , 0 ))).value ));
        	}//インスタンスがCqMatrixtのとき
        	else if(t instanceof CqMatrix)
        	{
        		((CqMatrix)pTResult2.pValue_get( 2 , 0 )).assignment((CqMatrix)pParam.pValue_get( 2 , 0 ));
        		((CqMatrix)pTResult2.pValue_get( 3 , 0 )).assignment((CqMatrix)pParam.pValue_get( 3 , 0 ));
        		((CqMatrix)pTResult1.pValue_get( 2 , 0 )).assignment(((CqMatrix)pTResult2.pValue_get( 0 , 0 )).assignment((((CqMatrix)(pParam.pValue_get( 0 , 0 ))).add(((CqMatrix)(pParam.pValue_get( 2 , 0 ))) )).multiply(0.5f)));
        		((CqMatrix)pTResult1.pValue_get( 3 , 0 )).assignment(((CqMatrix)pTResult2.pValue_get( 1 , 0 )).assignment((((CqMatrix)(pParam.pValue_get( 1 , 0 ))).add(((CqMatrix)(pParam.pValue_get( 3 , 0 ))) )).multiply(0.5f)));	                		                	
        	}//インスタンスがCqColorのとき
        	else if(t instanceof CqColor)
        	{
        		((CqColor)pTResult2.pValue_get( 2 , 0 )).assignment(((CqColor)pParam.pValue_get( 2 , 0 )));
        		((CqColor)pTResult2.pValue_get( 3 , 0 )).assignment(((CqColor)pParam.pValue_get( 3 , 0 )));
        		((CqColor)pTResult1.pValue_get( 2 , 0 )).assignment((((CqColor)pTResult2.pValue_get( 0 , 0 )).assignment(((((CqColor)(pParam.pValue_get( 0 , 0 ))).add((CqColor)(pParam.pValue_get( 2 , 0 )))).mul(0.5f)))));
        		((CqColor)pTResult1.pValue_get( 3 , 0 )).assignment((((CqColor)pTResult2.pValue_get( 1 , 0 )).assignment(((((CqColor)(pParam.pValue_get( 1 , 0 ))).add((CqColor)(pParam.pValue_get( 3 , 0 )))).mul(0.5f)))));	                		                	
        		
        	}//インスタンスがCqVector3Dのとき
        	else if(t instanceof CqVector3D)
        	{
        		((CqVector3D)pTResult2.pValue_get( 2 ,0 )).assignment((CqVector3D)pParam.pValue_get( 2 , 0 ));
        		((CqVector3D)pTResult2.pValue_get( 3 , 0 )).assignment((CqVector3D)pParam.pValue_get( 3 , 0 ));
        		((CqVector3D)pTResult1.pValue_get( 2 , 0 )).assignment(((CqVector3D)pTResult2.pValue_get( 0 , 0 )).assignment((((CqVector3D)(pParam.pValue_get( 0 , 0 ))).add(((CqVector3D)(pParam.pValue_get( 2 , 0 ))) )).mul(0.5f)));
        		((CqVector3D)pTResult1.pValue_get( 3 , 0 )).assignment(((CqVector3D)pTResult2.pValue_get( 1 , 0 )).assignment((((CqVector3D)(pParam.pValue_get( 1 , 0 ))).add(((CqVector3D)(pParam.pValue_get( 3 , 0 ))) )).mul(0.5f)));	                		                	
        	}//インスタンスがCqVector4Dのとき
        	else if(t instanceof CqVector4D)
        	{
        		((CqVector4D)pTResult2.pValue_get( 2 , 0 )).assignment((CqVector4D)pParam.pValue_get( 2 , 0 ));
        		((CqVector4D)pTResult2.pValue_get( 3 , 0 )).assignment((CqVector4D)pParam.pValue_get( 3 , 0 ));
        		((CqVector4D)pTResult1.pValue_get( 2 , 0 )).assignment(((CqVector4D)pTResult2.pValue_get( 0 , 0 )).assignment((((CqVector4D)(pParam.pValue_get( 0 , 0 ))).add(((CqVector4D)(pParam.pValue_get( 2 , 0 ))) )).mul(0.5f)));
        		((CqVector4D)pTResult1.pValue_get( 3 , 0 )).assignment(((CqVector4D)pTResult2.pValue_get( 1 , 0 )).assignment((((CqVector4D)(pParam.pValue_get( 1 , 0 ))).add(((CqVector4D)(pParam.pValue_get( 3 , 0 ))) )).mul(0.5f)));	                		                	
        	}else{ //　想定しないインスタンスの型。
        	}
        }
    }
    
	/**
     * @see net.cellcomputing.himawari.library.IqSurface#Transform(net.cellcomputing.himawari.library.types.CqMatrix, net.cellcomputing.himawari.library.types.CqMatrix, net.cellcomputing.himawari.library.types.CqMatrix, int)
     */
    @SuppressWarnings("unchecked")
	@Override
	//nttdata 高速化
//    public void Transform(CqMatrix matTx, CqMatrix matITTx, CqMatrix matRTx, int iTime) {
//    	
//    	// Tansform the control hull by the specified matrix.
//    	for( CqParameter iUP : m_aUserParams )
//    	{
//    		int i;
//    		
//    		if ( iUP.Type().getValue() == type_point )
//    		{
//    			
//    			CqParameterTyped<CqVector3D, CqVector3D> pTPV = (CqParameterTyped<CqVector3D, CqVector3D>)( iUP );
//    			int size = iUP.Size();
////    			nttdata 高速化
////    			for ( i = 0; i < size; i++ ) 
////    				((CqVector3D)pTPV.pValue()[ i ]).assignment( matTx.multiply((CqVector3D)(pTPV.pValue() [ i ] )));
//    			Object tmp[];
//    			tmp = pTPV.pValue();
//    			for ( i = 0; i < size; i++ ) 
//    				((CqVector3D)tmp[ i ]).assignment( matTx.multiply((CqVector3D)( tmp[ i ] )));
//    		}
//    		else if ( iUP.Type().getValue() == type_normal )
//    		{
//    			CqParameterTyped<CqVector3D, CqVector3D> pTPV = (CqParameterTyped<CqVector3D, CqVector3D>)( iUP );
//    			int size = iUP.Size();
////    			nttdata 高速化
////    			for ( i = 0; i < size; i++ )
////    				((CqVector3D)pTPV.pValue() [ i ]).assignment( matITTx.multiply( (CqVector3D)( pTPV.pValue() [ i ] )));
//    			Object tmp[];
//    			tmp = pTPV.pValue();
//    			for ( i = 0; i < size; i++ )
//    				((CqVector3D)tmp[ i ]).assignment( matITTx.multiply( (CqVector3D)( tmp[ i ] )));
//    		}
//    		else if ( iUP.Type().getValue() == type_vector )
//    		{
//    			CqParameterTyped<CqVector3D, CqVector3D> pTPV = (CqParameterTyped<CqVector3D, CqVector3D>)( iUP );
//    			int size = iUP.Size();
////    			nttdata 高速化
////    			for ( i = 0; i < size; i++ )
////    				((CqVector3D)pTPV.pValue() [ i ]).assignment( matRTx.multiply( (CqVector3D)( pTPV.pValue() [ i ] )));
//    			Object tmp[];
//    			tmp = pTPV.pValue();
//    			for ( i = 0; i < size; i++ )
//    				((CqVector3D)tmp[ i ]).assignment( matRTx.multiply( (CqVector3D)( tmp[ i ] )));
//    		}
//    		else if ( iUP.Type().getValue() == type_hpoint )
//    		{
//    			CqParameterTyped<CqVector4D, CqVector3D> pTPV = (CqParameterTyped<CqVector4D, CqVector3D>)( iUP );
//    			int size = iUP.Size();
//    			//nttdata 高速化
////    			for ( i = 0; i < size; i++ )
////    				((CqVector4D)pTPV.pValue() [ i ]).assignment( matTx.multiply( (CqVector4D)( pTPV.pValue() [ i ] )));
//    			Object tmp[];
//    			tmp = pTPV.pValue();
//    			for ( i = 0; i < size; i++ )
//    				((CqVector4D)tmp[ i ]).assignment( matTx.multiply( (CqVector4D)( tmp[ i ] )));
//    		}
//    	}
//    	
//    }
public void Transform(CqMatrix matTx, CqMatrix matITTx, CqMatrix matRTx, int iTime) {
    	
    	// Tansform the control hull by the specified matrix.
    	for( CqParameter iUP : m_aUserParams )
    	{
    		int i;
    		
    		if ( iUP.Type().getValue() == type_point )
    		{
    			
    			CqParameterTyped<CqVector3D, CqVector3D> pTPV = (CqParameterTyped<CqVector3D, CqVector3D>)( iUP );
    			int size = iUP.Size();
    			for ( i = 0; i < size; i++ ) 
    				((CqVector3D)pTPV.pValue_get(0 , i )).assignment( matTx.multiply((CqVector3D)(pTPV.pValue_get(0, i ) )));
    		}
    		else if ( iUP.Type().getValue() == type_normal )
    		{
    			CqParameterTyped<CqVector3D, CqVector3D> pTPV = (CqParameterTyped<CqVector3D, CqVector3D>)( iUP );
    			int size = iUP.Size();
    			for ( i = 0; i < size; i++ )
    				((CqVector3D)pTPV.pValue_get(0 , i )).assignment( matITTx.multiply( (CqVector3D)( pTPV.pValue_get(0 , i ) )));
    		}
    		else if ( iUP.Type().getValue() == type_vector )
    		{
    			CqParameterTyped<CqVector3D, CqVector3D> pTPV = (CqParameterTyped<CqVector3D, CqVector3D>)( iUP );
    			int size = iUP.Size();
    			for ( i = 0; i < size; i++ )
    				((CqVector3D)pTPV.pValue_get(0 , i )).assignment( matRTx.multiply( (CqVector3D)( pTPV.pValue_get(0 , i ) )));
    		}
    		else if ( iUP.Type().getValue() == type_hpoint )
    		{
    			CqParameterTyped<CqVector4D, CqVector3D> pTPV = (CqParameterTyped<CqVector4D, CqVector3D>)( iUP );
    			int size = iUP.Size();
    			for ( i = 0; i < size; i++ )
    				((CqVector4D)pTPV.pValue_get(0 , i )).assignment( matTx.multiply( (CqVector4D)( pTPV.pValue_get(0 , i ) )));
    		}
    	}
    	
    }
    
    /* (non-Javadoc)
     * @see net.cellcomputing.himawari.library.IqSurface#PreDice(int, int)
     */
    @Override
    public void PreDice(int uDiceSize, int vDiceSize) 
    {}
    
    /**
     * @see net.cellcomputing.himawari.library.CqBasicSurface#NaturalDice(net.cellcomputing.himawari.library.CqParameter, int, int, net.cellcomputing.himawari.library.IqShaderData)
     */
    @SuppressWarnings("unchecked")
	@Override
    public void NaturalDice(CqParameter pParameter, int uDiceSize, int vDiceSize, IqShaderData pData) 
    {
    	switch ( pParameter.Type().getValue() )
    	{
    	case type_float:
    	{
    		CqParameterTyped<p_float, p_float> pTParam = (CqParameterTyped<p_float, p_float>)( pParameter );
    		TypedNaturalDice( uDiceSize, vDiceSize, pTParam, pData );
    		break;
    	}
    	
    	case type_integer:
    	{
    		CqParameterTyped<p_int, p_float> pTParam = (CqParameterTyped<p_int, p_float>)( pParameter );
    		TypedNaturalDice( uDiceSize, vDiceSize, pTParam, pData );
    		break;
    	}
    	
    	case type_point:
    	case type_vector:
    	case type_normal:
    	{
    		CqParameterTyped<CqVector3D, CqVector3D> pTParam = (CqParameterTyped<CqVector3D, CqVector3D>)( pParameter );
    		TypedNaturalDice( uDiceSize, vDiceSize, pTParam, pData );
    		break;
    	}
    	
    	case type_hpoint:
    	{
    		CqParameterTyped<CqVector4D, CqVector3D> pTParam = (CqParameterTyped<CqVector4D, CqVector3D>)( pParameter );
    		TypedNaturalDice( uDiceSize, vDiceSize, pTParam, pData );
    		break;
    	}
    	
    	case type_color:
    	{
    		CqParameterTyped<CqColor, CqColor> pTParam = (CqParameterTyped<CqColor, CqColor>)( pParameter );
    		TypedNaturalDice( uDiceSize, vDiceSize, pTParam, pData );
    		break;
    	}
    	
    	case type_string:
    	{
    		CqParameterTyped<p_String, p_String> pTParam = (CqParameterTyped<p_String, p_String>)( pParameter );
    		TypedNaturalDice( uDiceSize, vDiceSize, pTParam, pData );
    		break;
    	}
    	
    	case type_matrix:
    	{
    		CqParameterTyped<CqMatrix, CqMatrix> pTParam = (CqParameterTyped<CqMatrix, CqMatrix>)( pParameter );
    		TypedNaturalDice( uDiceSize, vDiceSize, pTParam, pData );
    		break;
    	}
    	
    	default:
    	{
    		// left blank to avoid compiler warnings about unhandled types
    		break;
    	}
    	}    	
    }
    
    
    /* (non-Javadoc)
     * @see net.cellcomputing.himawari.library.IqSurface#PostDice(net.cellcomputing.himawari.library.CqMicroPolyGrid)
     */
    @Override
    public void PostDice(CqMicroPolyGrid pGrid) 
    {}
    
 
    /* (non-Javadoc)
     * @see net.cellcomputing.himawari.library.IqSurface#PreSubdivide(net.cellcomputing.himawari.accessory.STLVector, boolean)
     */
    @Override
    public int PreSubdivide(STLVector<CqBasicSurface> aSplits, boolean u) {
    	return 0;
    }
    
    
    /* (non-Javadoc)
     * @see net.cellcomputing.himawari.library.IqSurface#NaturalSubdivide(net.cellcomputing.himawari.library.CqParameter, net.cellcomputing.himawari.library.CqParameter, net.cellcomputing.himawari.library.CqParameter, boolean)
     */
    @SuppressWarnings("unchecked")
	@Override
    public void NaturalSubdivide(CqParameter pParam, CqParameter pParam1, CqParameter pParam2, boolean u) 
    {
        switch ( pParam.Type().getValue() )
        {
        case type_float:
            {
                CqParameterTyped<p_float, p_float> pTParam = (CqParameterTyped<p_float, p_float>)( pParam );
                CqParameterTyped<p_float, p_float> pTResult1 = (CqParameterTyped<p_float, p_float>)( pParam1 );
                CqParameterTyped<p_float, p_float> pTResult2 = (CqParameterTyped<p_float, p_float>)( pParam2 );
                TypedNaturalSubdivide( pTParam, pTResult1, pTResult2, u );
                break;
            }

        case type_integer:
            {
                CqParameterTyped<p_int, p_float> pTParam = (CqParameterTyped<p_int, p_float>)( pParam );
                CqParameterTyped<p_int, p_float> pTResult1 = (CqParameterTyped<p_int, p_float>)( pParam1 );
                CqParameterTyped<p_int, p_float> pTResult2 = (CqParameterTyped<p_int, p_float>)( pParam2 );
                TypedNaturalSubdivide( pTParam, pTResult1, pTResult2, u );
                break;
            }

        case type_point:
        case type_vector:
        case type_normal:
            {
                CqParameterTyped<CqVector3D, CqVector3D> pTParam = (CqParameterTyped<CqVector3D, CqVector3D>)( pParam );
                CqParameterTyped<CqVector3D, CqVector3D> pTResult1 = (CqParameterTyped<CqVector3D, CqVector3D>)( pParam1 );
                CqParameterTyped<CqVector3D, CqVector3D> pTResult2 = (CqParameterTyped<CqVector3D, CqVector3D>)( pParam2 );
                TypedNaturalSubdivide( pTParam, pTResult1, pTResult2, u );
                break;
            }

        case type_hpoint:
            {
                CqParameterTyped<CqVector4D, CqVector3D> pTParam = (CqParameterTyped<CqVector4D, CqVector3D>)( pParam );
                CqParameterTyped<CqVector4D, CqVector3D> pTResult1 = (CqParameterTyped<CqVector4D, CqVector3D>)( pParam1 );
                CqParameterTyped<CqVector4D, CqVector3D> pTResult2 = (CqParameterTyped<CqVector4D, CqVector3D>)( pParam2 );
                TypedNaturalSubdivide( pTParam, pTResult1, pTResult2, u );
                break;
            }


        case type_color:
            {
                CqParameterTyped<CqColor, CqColor> pTParam = (CqParameterTyped<CqColor, CqColor>)( pParam );
                CqParameterTyped<CqColor, CqColor> pTResult1 = (CqParameterTyped<CqColor, CqColor>)( pParam1 );
                CqParameterTyped<CqColor, CqColor> pTResult2 = (CqParameterTyped<CqColor, CqColor>)( pParam2 );
                TypedNaturalSubdivide( pTParam, pTResult1, pTResult2, u );
                break;
            }

        case type_string:
            {
                CqParameterTyped<p_String, p_String> pTParam = (CqParameterTyped<p_String, p_String>)( pParam );
                CqParameterTyped<p_String, p_String> pTResult1 = (CqParameterTyped<p_String, p_String>)( pParam1 );
                CqParameterTyped<p_String, p_String> pTResult2 = (CqParameterTyped<p_String, p_String>)( pParam2 );
                TypedNaturalSubdivide( pTParam, pTResult1, pTResult2, u );
                break;
            }

        case type_matrix:
            {
                CqParameterTyped<CqMatrix, CqMatrix> pTParam = (CqParameterTyped<CqMatrix, CqMatrix>)( pParam );
                CqParameterTyped<CqMatrix, CqMatrix> pTResult1 = (CqParameterTyped<CqMatrix, CqMatrix>)( pParam1 );
                CqParameterTyped<CqMatrix, CqMatrix> pTResult2 = (CqParameterTyped<CqMatrix, CqMatrix>)( pParam2 );
                TypedNaturalSubdivide( pTParam, pTResult1, pTResult2, u );
                break;
            }

        default:
            {
                // blank to avoid compiler warnings about unhandled cases
                break;
            }
        }
    }
    
    
    /* (non-Javadoc)
     * @see net.cellcomputing.himawari.library.IqSurface#PostSubdivide(net.cellcomputing.himawari.accessory.STLVector)
     */
    @Override
    public void PostSubdivide(STLVector<CqBasicSurface> aSplits) 
    {}
    
    
    /* (non-Javadoc)
     * @see net.cellcomputing.himawari.library.CqBasicSurface#Dice()
     */
    @Override
    public CqMicroPolyGridBase Dice() 
    {
        PreDice( m_uDiceSize, m_vDiceSize );

        // Create a new CqMicorPolyGrid for this patch
        CqMicroPolyGrid pGrid = new CqMicroPolyGrid( m_uDiceSize, m_vDiceSize, this );

        int lUses = Uses();

        // Allow the surface to fill in as much as possible on the grid in one go for speed.
        int lDone = DiceAll( pGrid );

        // Dice the primitive variables.

        // Special cases for s and t if "st" exists, it should override s and t.
        CqParameter pParam;
        if( ( pParam = FindUserParam("st") ) != null )
        {
            if ( !isDONE( lDone, EnvVars_s ) && USES( lUses, EnvVars_s ) && ( null != pGrid.pVar(EnvVars_s) ) )
                pParam .DiceOne( m_uDiceSize, m_vDiceSize, pGrid.pVar(EnvVars_s), this, 0 );
            if ( !isDONE( lDone, EnvVars_t ) && USES( lUses, EnvVars_t ) && ( null != pGrid.pVar(EnvVars_t) ) )
                pParam .DiceOne( m_uDiceSize, m_vDiceSize, pGrid.pVar(EnvVars_t), this, 1 );
            
            lDone = lDone | ( 0x00000001 << EnvVars_s );	// DONE( lDone, EnvVars_s);
            lDone = lDone | ( 0x00000001 << EnvVars_t );	// DONE( lDone, EnvVars_t);
        }

        // Loop over all the variables checking if they have been specified in the scene, and
        // if they are needed by the shaders, and id the grid can accept them.
        // If all the tests pass, dice them into the grid based on their type.

        int varID;
        for( varID = EnvVars_Cs; varID != EnvVars_Last; varID++ )
        {
            if ( !isDONE( lDone, varID ) && USES( lUses, varID ) && ( null != pGrid.pVar(varID) ) )
            {
                // Check if Cs has been specified by the user.
                if ( bHasVar(varID) )
                {
                    if( pVar(varID).Class().getValue() == class_vertex || pVar(varID).Class().getValue() == class_facevarying )
                        // "vertex" and "facevarying" need to be dealt with by the surface as they are diced using the
                        // natural subdivision algorithms for that particular surface.
                        NaturalDice( pVar(varID), m_uDiceSize, m_vDiceSize, pGrid.pVar(varID) );
                    else
                        // "varying" are just bilinearly interpolated, so can be handled by the primitive variable.
                        pVar(varID).Dice( m_uDiceSize, m_vDiceSize, pGrid.pVar(varID), this );
                     
                    // Mark this as done, so that the special case default handlers later don't need to worry about it.
//                    DONE(lDone, varID);
                    lDone= lDone | ( 0x00000001 << varID );
                }
            }
        }

        // Special case handlers for primitive variables that have defaults.
        if ( !isDONE( lDone, EnvVars_Cs ) && USES( lUses, EnvVars_Cs ) && ( null != pGrid.pVar(EnvVars_Cs) ) )
        {
            if ( null != pAttributes() .GetColorAttribute( "System", "Color" ) )
                pGrid.pVar(EnvVars_Cs) .SetColor( new CqColor(pAttributes().GetColorAttribute( "System", "Color" ) [ 0 ] ));
            else
                pGrid.pVar(EnvVars_Cs) .SetColor( new CqColor( 1f, 1f, 1f ) );
        }

        if ( !isDONE( lDone, EnvVars_Os ) && USES( lUses, EnvVars_Os ) && ( null != pGrid.pVar(EnvVars_Os) ) )
        {
            if ( null != pAttributes() .GetColorAttribute( "System", "Opacity" ) )
                pGrid.pVar(EnvVars_Os) .SetColor( new CqColor( pAttributes() .GetColorAttribute( "System", "Opacity" ) [ 0 ] )) ;
            else
                pGrid.pVar(EnvVars_Os) .SetColor( new  CqColor( 1f, 1f, 1f ) );
        }

        // If the shaders need N and they have been explicitly specified, then bilinearly interpolate them.
        if ( isDONE( lDone, EnvVars_N ) )
            pGrid.SetbShadingNormals( true );

        if ( !isDONE( lDone, EnvVars_Ng ) && CanGenerateNormals() && USES( lUses, EnvVars_Ng ) )
        {
            GenerateGeometricNormals( m_uDiceSize, m_vDiceSize, pGrid.pVar(EnvVars_Ng) );
            pGrid.SetbGeometricNormals( true );
        }

        // Now we need to dice the user specified parameters as appropriate.
        for( CqParameter iUP : m_aUserParams )
        {
            IqShader pShader;
            
            pShader = pGrid.pAttributes().pshadSurface(QGetRenderContext().Time());
    		if ( pShader != null )
                pShader.SetArgument( iUP, this );
    		
    		pShader = pGrid.pAttributes().pshadDisplacement(QGetRenderContext().Time());
            if ( pShader != null )
                pShader.SetArgument( iUP, this );
            
    		pShader = pGrid.pAttributes().pshadAtmosphere(QGetRenderContext().Time());
            if ( pShader != null )
                pShader.SetArgument( iUP, this );
        }

        PostDice( pGrid );

        return ( pGrid );
    }
    
    
    /* (non-Javadoc)
     * @see net.cellcomputing.himawari.library.CqBasicSurface#Split(net.cellcomputing.himawari.accessory.STLVector)
     */
    @Override
    public int Split(STLVector<CqBasicSurface> aSplits)
    {
        int cSplits = PreSubdivide( aSplits, m_SplitDir.getValue() == SplitDir_U );

        assert( aSplits.size() == 2 );
        
        aSplits.get( 0 ).SetSurfaceParameters( this );
        aSplits.get( 0 ).SetSplitDir( ( SplitDir() == SplitDir_U ) ? new EqSplitDir(SplitDir_V) : new EqSplitDir(SplitDir_U) );
        aSplits.get( 0 ).SetEyeSplitCount( EyeSplitCount() );
        aSplits.get( 0 ).m_fDiceable = true;
        //ADDREF( aSplits[ 0 ] );　元からコメントアウト

        aSplits.get( 1 ).SetSurfaceParameters( this );
        aSplits.get( 1 ).SetSplitDir( ( SplitDir() == SplitDir_U ) ? new EqSplitDir(SplitDir_V) : new EqSplitDir(SplitDir_U) );
        aSplits.get( 1 ).SetEyeSplitCount( EyeSplitCount() );
        aSplits.get( 1 ).m_fDiceable = true;
        //ADDREF( aSplits[ 1 ] );　元からコメントアウト

        // Iterate through any use parameters subdividing and storing the second value in the target surface.
        boolean direction = ( SplitDir() == SplitDir_U );
        for( CqParameter iUP : m_aUserParams )
        {
            CqParameter pNewA = iUP.Clone();
            CqParameter pNewB = iUP.Clone();
            iUP.Subdivide( pNewA, pNewB, direction , this );
            ((CqSurface)aSplits.get( 0 )).AddPrimitiveVariable( pNewA );
            ((CqSurface)aSplits.get( 1 )).AddPrimitiveVariable( pNewB );
        }

        if ( !m_fDiceable )
        {
            STLVector< CqBasicSurface > aSplits0 = new STLVector< CqBasicSurface >( CqBasicSurface.class );
            STLVector< CqBasicSurface > aSplits1 = new STLVector< CqBasicSurface >( CqBasicSurface.class );

            cSplits = aSplits.get( 0 ).Split( aSplits0 );
            cSplits += aSplits.get( 1 ).Split( aSplits1 );

            aSplits.clear();
       
            //aSplits.swap( aSplits0 );
            aSplits.addAll( aSplits0 );
            aSplits0.clear();
            aSplits.addAll( aSplits1 );
        }

        PostSubdivide( aSplits );

        return ( aSplits.size() );
    }
    
    
    /* (non-Javadoc)
     * @see net.cellcomputing.himawari.library.CqBasicSurface#Diceable()
     */
    @Override
    public boolean Diceable() {
    	return false;
    }
    
    
    
	//************************************************************************//
	//*** 演算子のオーバーロード
	//************************************************************************//
	/**
	 * 
	 * 代入演算子。
	 * 各要素を代入する。
	 * 	
	 * @param From	代入元
	 * @return	自分自身
	 */
	public CqSurface assignment( final CqSurface From )
	{
	    super.assignment( From );
	    
	    // Nullify the standard primitive variables index table.
	    int i;
	    for ( i = 0; i < EnvVars_Last; i++ )
	        m_aiStdPrimitiveVars[ i ] = -1;
	    return ( this );
	}


}
