📄 tobezier.cc
字号:
/*** License Applicability. Except to the extent portions of this file are** made subject to an alternative license as permitted in the SGI Free** Software License B, Version 1.1 (the "License"), the contents of this** file are subject only to the provisions of the License. You may not use** this file except in compliance with the License. You may obtain a copy** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:**** http://oss.sgi.com/projects/FreeB**** Note that, as provided in the License, the Software is distributed on an** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.**** Original Code. The Original Code is: OpenGL Sample Implementation,** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.** Copyright in any portions created by third parties is as indicated** elsewhere herein. All Rights Reserved.**** Additional Notice Provisions: The application programming interfaces** established by SGI in conjunction with the Original Code are The** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X** Window System(R) (Version 1.3), released October 19, 1998. This software** was created using the OpenGL(R) version 1.2.1 Sample Implementation** published by SGI, but has not been independently verified as being** compliant with the OpenGL(R) version 1.2.1 Specification.*//* * tobezier.c++ * * $Date: 2006/03/14 15:08:52 $ $Revision: 1.2 $ * $Header: /home/krh/git/sync/mesa-cvs-repo/Mesa/src/glu/sgi/libnurbs/internals/tobezier.cc,v 1.2 2006/03/14 15:08:52 brianp Exp $ */#include "glimports.h"#include "myassert.h"#include "mystdio.h"#include "mystring.h"#include "quilt.h"#include "knotvector.h"/* local type definitions */struct Breakpt { /* breakpoints */ Knot value; /* value */ int multi; /* multiplicity */ int def; /* deficit */};struct Knotspec { /* knotvector format */ long order; /* order of spline */ Knot_ptr inkbegin; /* input knot sequence */ Knot_ptr inkend; /* location after last knot */ Knot_ptr outkbegin; /* in-process knot subsequence */ Knot_ptr outkend; /* location after last knot */ Knot_ptr kleft; /* */ Knot_ptr kright; /* */ Knot_ptr kfirst; /* */ Knot_ptr klast; /* */ Knot_ptr sbegin; /* conversion factor values */ Breakpt * bbegin; /* in-process breakpoints */ Breakpt * bend; /* last breakpoint */ int ncoords; /* coordinates per control point */ int prestride; /* stride between input points */ int poststride; /* stride between output points */ int preoffset; /* scaled point offset */ int postoffset; /* scaled point offset */ int prewidth; /* width of dimension */ int postwidth; /* width of dimension */ int istransformed; /* was dimension transformed */ Knotspec * next; /* next knotspec */ Knotspec * kspectotrans; /* knotspec in transformation direction */ Knotspec( void ); ~Knotspec( void ); void factors( void ); void insert( REAL * ); void preselect(); void select( void ); void copy( INREAL *, REAL * ); void breakpoints( void ); void knots( void ); void transform( REAL * ); void showpts( REAL * ); void pt_io_copy( REAL *, INREAL * ); void pt_oo_copy( REAL *, REAL * ); void pt_oo_sum( REAL*, REAL*, REAL*, Knot, Knot );};struct Splinespec { /* a non-uniform tensor element */ Splinespec( int ); ~Splinespec(void); Knotspec *kspec; /* format of each param. dir. */ int dim; /* domain dimension */ REAL * outcpts; /* Bezier control points */ void kspecinit( Knotvector & ); void kspecinit( Knotvector &, Knotvector & ); void select( void ); void layout( long ); void setupquilt( Quilt_ptr ); void copy( INREAL * ); void transform( void );};/*----------------------------------------------------------------------------- * Quilt::toBezier - convert from NURBS to rational Bezier *----------------------------------------------------------------------------- */voidQuilt::toBezier( Knotvector& knotvector, /* a knot vector */ INREAL *ctlpts, /* input contol points */ long ncoords ) /* number of coordinates per control point */{ Splinespec spline( 1 ); spline.kspecinit( knotvector ); spline.select(); spline.layout( ncoords ); spline.setupquilt( this ); spline.copy( ctlpts ); spline.transform();}voidQuilt::toBezier( Knotvector& sknotvector, /* a knot vector */ Knotvector& tknotvector, /* a knot vector */ INREAL *ctlpts, /* input contol points */ long ncoords ) /* number of coordinates per control point */{ Splinespec spline( 2 ); spline.kspecinit( sknotvector, tknotvector ); spline.select(); spline.layout( ncoords ); spline.setupquilt( this ); spline.copy( ctlpts ); spline.transform();}Splinespec::Splinespec( int dimen ){ dim = dimen;}Splinespec::~Splinespec( void ){ /* Note: do NOT delete 'outcpts' here since its address (not contents) * is copied in 'cpts' in this file in function Splinespec::setupquilt(). * This block of memory will eventually be deleted in file quilt.c++ in * function Quilt::deleteMe() through 'cpts' so do NOT delete it here! */ Knotspec *ktrav= kspec; //start at beginning of list while (ktrav != 0) { //any items to delete? Knotspec *deleteThis= ktrav; //remember to delete this ktrav= ktrav->next; //go to next item if any delete deleteThis; //delete it } } /* ~Splinespec() *//*----------------------------------------------------------------------------- * Splinespec::kspecinit - initialize Splinespec structure * * Client: Quilt::toBezier *----------------------------------------------------------------------------- */voidSplinespec::kspecinit( Knotvector& knotvector ){ kspec = new Knotspec; kspec->inkbegin = knotvector.knotlist; kspec->inkend = knotvector.knotlist + knotvector.knotcount; kspec->prestride = (int) knotvector.stride; kspec->order = knotvector.order; kspec->next = NULL;}voidSplinespec::kspecinit( Knotvector& sknotvector, Knotvector& tknotvector ){ kspec = new Knotspec; Knotspec *tkspec = new Knotspec; kspec->inkbegin = sknotvector.knotlist; kspec->inkend = sknotvector.knotlist + sknotvector.knotcount; kspec->prestride = (int) sknotvector.stride; kspec->order = sknotvector.order; kspec->next = tkspec; tkspec->inkbegin = tknotvector.knotlist; tkspec->inkend = tknotvector.knotlist + tknotvector.knotcount; tkspec->prestride = (int) tknotvector.stride; tkspec->order = tknotvector.order; tkspec->next = NULL;}/*----------------------------------------------------------------------------- * Splinespec::select - select the subsegments to copy * * Client: gl_quilt_to_bezier *----------------------------------------------------------------------------- */voidSplinespec::select( ){ for( Knotspec *knotspec = kspec; knotspec; knotspec = knotspec->next ) { knotspec->preselect(); knotspec->select(); }}/*----------------------------------------------------------------------------- * Splinespec::layout - * * Client: gl_quilt_to_bezier *----------------------------------------------------------------------------- */voidSplinespec::layout( long ncoords ){ long stride = ncoords; for( Knotspec *knotspec = kspec; knotspec; knotspec=knotspec->next ) { knotspec->poststride = (int) stride; stride *= ((knotspec->bend-knotspec->bbegin)*knotspec->order + knotspec->postoffset); knotspec->preoffset *= knotspec->prestride; knotspec->prewidth *= knotspec->poststride; knotspec->postwidth *= knotspec->poststride; knotspec->postoffset *= knotspec->poststride; knotspec->ncoords = (int) ncoords; } outcpts = new REAL[stride]; assert( outcpts != 0 ); }/*----------------------------------------------------------------------------- * Splinespec::copy - copy the control points of current subobject * * Client: gl_quilt_to_bezier *----------------------------------------------------------------------------- */voidSplinespec::copy( INREAL *incpts ){ kspec->copy( incpts, outcpts );}/*----------------------------------------------------------------------------- * Splinespec::setupquilt - assign all quilt variables from knotspec * * Client: gl_quilt_to_bezier *----------------------------------------------------------------------------- */voidSplinespec::setupquilt( Quilt_ptr quilt ){ Quiltspec_ptr qspec = quilt->qspec; quilt->eqspec = qspec + dim; for( Knotspec *knotspec = kspec; knotspec; knotspec=knotspec->next, qspec++ ) { qspec->stride = knotspec->poststride; qspec->width = knotspec->bend - knotspec->bbegin; qspec->order = (int) knotspec->order; qspec->offset = knotspec->postoffset; qspec->index = 0; qspec->bdry[0] = (knotspec->kleft == knotspec->kfirst) ? 1 : 0; qspec->bdry[1] = (knotspec->kright == knotspec->klast) ? 1 : 0; qspec->breakpoints = new Knot[qspec->width+1]; Knot_ptr k = qspec->breakpoints; for( Breakpt *bk = knotspec->bbegin; bk <= knotspec->bend; bk++ ) *(k++) = bk->value; } quilt->cpts = outcpts; quilt->next = 0;}/*----------------------------------------------------------------------------- * Splinespec::transform - convert a spline to Bezier format * * Client: gl_quilt_to_bezier *----------------------------------------------------------------------------- */voidSplinespec::transform( void ){ Knotspec *knotspec; for( knotspec = kspec; knotspec; knotspec=knotspec->next ) knotspec->istransformed = 0; for( knotspec = kspec; knotspec; knotspec=knotspec->next ) { for( Knotspec *kspec2 = kspec; kspec2; kspec2=kspec2->next ) kspec2->kspectotrans = knotspec; kspec->transform( outcpts ); knotspec->istransformed = 1; }}/*----------------------------------------------------------------------------- * Knotspec::Knotspec - constuct a knot spec *----------------------------------------------------------------------------- */Knotspec::Knotspec( void ){ bbegin = 0; sbegin = 0; outkbegin = 0;}/*----------------------------------------------------------------------------- * Knotspec::copy - copy the control points along minor direction * * Client: Splinespec::copy *----------------------------------------------------------------------------- */voidKnotspec::copy( INREAL *inpt, REAL *outpt ){ inpt = (INREAL *) (((char *) inpt) + preoffset); if( next ) { for( REAL *lpt=outpt+prewidth; outpt != lpt; outpt += poststride ) { next->copy( inpt, outpt ); inpt = (INREAL *) (((char *) inpt) + prestride); } } else { for( REAL *lpt=outpt+prewidth; outpt != lpt; outpt += poststride ) { pt_io_copy( outpt, inpt ); inpt = (INREAL *) (((char *) inpt) + prestride); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -