X3D CAD/TransposeNurbsAxes
From Web3D.org
Revision as of 13:20, 22 March 2012 by Vmarchetti (Talk | contribs)
The web page [[1]] demonstrates a disagreement among current X3D browsers that implement the NURBS Component as to how they interpret the standard to place the parametric axes (generally labelled the u-v axes) on the created and rendered 2D surface.
<?xml version="1.0" encoding="ISO-8859-1"?> <!-- Transposes the u-v parametric coordinate axes on a NurbsPatchSurface or NurbsTrimmedSurface For NurbsPatchSurface nodes and TrimmedNurbsSurface node the parameters which come in u-v pairs (ex uKnot, vKnot) have their values swapped The attributes NurbsPatchSurface/@weight and NurbsPatchSurface/Coordinate/@point are, in the input x3d data, lists of numbers which are the weight,control_points arrays listed in column-major order. In the transformed data these lists are the same arrays flattened in row-major order. For the nodes ContourPolyline2D/@controlPoint and NurbsCurve2D//@controlPoint: these attributes are lists of u-v coordinates of points in parametric coordinates. In the transformed attributes, each element of this list is transformed u,v ==> v,u The ordering of the list is unchanged. Copyright 2012 Vincent Marchetti This program 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 program 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 program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exsl="http://exslt.org/common" xmlns:str="http://exslt.org/strings" extension-element-prefixes="exsl" xmlns:ksh="http://kshell.com/ns/x3d"> <xsl:output method="xml" encoding="utf-8"/> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="NurbsPatchSurface/@uKnot|NurbsTrimmedSurface/@uKnot"> <xsl:if test="../@vKnot"> <xsl:attribute name="{name()}"> <xsl:value-of select="../@vKnot"/> </xsl:attribute> </xsl:if> </xsl:template> <xsl:template match="NurbsPatchSurface/@vKnot|NurbsTrimmedSurface/@vKnot"> <xsl:if test="../@uKnot"> <xsl:attribute name="{name()}"> <xsl:value-of select="../@uKnot"/> </xsl:attribute> </xsl:if> </xsl:template> <xsl:template match="NurbsPatchSurface/@uDimension|NurbsTrimmedSurface/@uDimension"> <xsl:if test="../@vDimension"> <xsl:attribute name="{name()}"> <xsl:value-of select="../@vDimension"/> </xsl:attribute> </xsl:if> </xsl:template> <xsl:template match="NurbsPatchSurface/@vDimension|NurbsTrimmedSurface/@vDimension"> <xsl:if test="../@uDimension"> <xsl:attribute name="{name()}"> <xsl:value-of select="../@uDimension"/> </xsl:attribute> </xsl:if> </xsl:template> <xsl:template match="NurbsPatchSurface/@uTessellation|NurbsTrimmedSurface/@uTessellation"> <xsl:if test="../@vTessellation"> <xsl:attribute name="{name()}"> <xsl:value-of select="../@vTessellation"/> </xsl:attribute> </xsl:if> </xsl:template> <xsl:template match="NurbsPatchSurface/@vTessellation|NurbsTrimmedSurface/@vTessellation"> <xsl:if test="../@uTessellation"> <xsl:attribute name="{name()}"> <xsl:value-of select="../@uTessellation"/> </xsl:attribute> </xsl:if> </xsl:template> <xsl:template match="NurbsPatchSurface/@uClosed|NurbsTrimmedSurface/@uClosed"> <xsl:if test="../@vClosed"> <xsl:attribute name="{name()}"> <xsl:value-of select="../@vClosed"/> </xsl:attribute> </xsl:if> </xsl:template> <xsl:template match="NurbsPatchSurface/@vClosed|NurbsTrimmedSurface/@vClosed"> <xsl:if test="../@uClosed"> <xsl:attribute name="{name()}"> <xsl:value-of select="../@uClosed"/> </xsl:attribute> </xsl:if> </xsl:template> <xsl:template match="NurbsPatchSurface/@uOrder|NurbsTrimmedSurface/@uOrder"> <xsl:if test="../@vOrder"> <xsl:attribute name="{name()}"> <xsl:value-of select="../@vOrder"/> </xsl:attribute> </xsl:if> </xsl:template> <xsl:template match="NurbsPatchSurface/@vOrder|NurbsTrimmedSurface/@vOrder"> <xsl:if test="../@uOrder"> <xsl:attribute name="{name()}"> <xsl:value-of select="../@uOrder"/> </xsl:attribute> </xsl:if> </xsl:template> <xsl:template match="NurbsPatchSurface/@weight|NurbsTrimmedSurface/@weight"> <xsl:attribute name="{name()}"> <xsl:variable name="transposed_weights"> <xsl:call-template name="ksh:transpose"> <xsl:with-param name="NC" select="number(../@vDimension)"/> <xsl:with-param name="NR" select="number(../@uDimension)"/> <xsl:with-param name="elements" select="str:split(normalize-space(.))"/> </xsl:call-template> </xsl:variable> <xsl:for-each select="exsl:node-set($transposed_weights)/token"> <xsl:value-of select="."/> <xsl:if test="last()>position()"><xsl:text> </xsl:text></xsl:if> </xsl:for-each> </xsl:attribute> </xsl:template> <xsl:template match="NurbsPatchSurface/Coordinate/@point|NurbsTrimmedSurface/Coordinate/@point"> <xsl:attribute name="{name()}"> <xsl:variable name="transposed_point"> <xsl:call-template name="ksh:transpose"> <xsl:with-param name="NC" select="number(../../@vDimension)"/> <xsl:with-param name="NR" select="number(../../@uDimension)"/> <xsl:with-param name="elements" select="str:split(.,',')"/> </xsl:call-template> </xsl:variable> <xsl:for-each select="exsl:node-set($transposed_point)/token"> <xsl:value-of select="."/> <xsl:if test="last() > position()"><xsl:text>, </xsl:text></xsl:if> </xsl:for-each> </xsl:attribute> </xsl:template> <!-- Templates for taking an array of nodes , NR rows and NC columns, output in column-major order, and preparing a node set of those nodes listed in row-major order --> <xsl:template name="ksh:transpose"> <xsl:param name="IR" select="1"/> <xsl:param name="NR"/> <xsl:param name="NC"/> <xsl:param name="elements"/> <!-- call the template which will list (in row major order the IR'th row --> <xsl:call-template name="ksh:transpose-row-out"> <xsl:with-param name="IR" select="$IR"/> <xsl:with-param name="NC" select="$NC"/> <xsl:with-param name="NR" select="$NR"/> <xsl:with-param name="elements" select="$elements"/> </xsl:call-template> <!-- the recursion: call this template starting at the next row --> <xsl:if test="$NR > $IR"> <xsl:call-template name="ksh:transpose"> <xsl:with-param name="IR" select="$IR + 1"/> <xsl:with-param name="NC" select="$NC"/> <xsl:with-param name="NR" select="$NR"/> <xsl:with-param name="elements" select="$elements"/> </xsl:call-template> </xsl:if> </xsl:template> <xsl:template name="ksh:transpose-row-out"> <xsl:param name="IC" select="1"/> <xsl:param name="IR"/> <xsl:param name="NR"/> <xsl:param name="NC"/> <xsl:param name="elements"/> <!-- send out the IC'th column of the IR'th row, using the indexing appropriate for column major indexing of the underlying list --> <xsl:param name="index" select="($IC -1)*$NR + $IR"/> <xsl:copy-of select="$elements[$index]"/> <!-- and the recursion, send out the rest of the columns of this row, starting at IC+1 --> <xsl:if test="$NC > $IC"> <xsl:call-template name="ksh:transpose-row-out"> <xsl:with-param name="IC" select="$IC + 1"/> <xsl:with-param name="IR" select="$IR"/> <xsl:with-param name="NC" select="$NC"/> <xsl:with-param name="NR" select="$NR"/> <xsl:with-param name="elements" select="$elements"/> </xsl:call-template> </xsl:if> </xsl:template> </xsl:stylesheet>