1 /* NAME: 2 E3GeometryDisk.c 3 4 DESCRIPTION: 5 Implementation of Quesa Pixmap Marker geometry class. 6 7 COPYRIGHT: 8 Copyright (c) 1999-2005, Quesa Developers. All rights reserved. 9 10 For the current release of Quesa, please see: 11 12 <http://www.quesa.org/> 13 14 Redistribution and use in source and binary forms, with or without 15 modification, are permitted provided that the following conditions 16 are met: 17 18 o Redistributions of source code must retain the above copyright 19 notice, this list of conditions and the following disclaimer. 20 21 o Redistributions in binary form must reproduce the above 22 copyright notice, this list of conditions and the following 23 disclaimer in the documentation and/or other materials provided 24 with the distribution. 25 26 o Neither the name of Quesa nor the names of its contributors 27 may be used to endorse or promote products derived from this 28 software without specific prior written permission. 29 30 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 31 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 32 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 33 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 34 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 35 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 36 TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 37 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 38 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 39 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 40 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 41 ___________________________________________________________________________ 42 */ 43 //============================================================================= 44 // Include files 45 //----------------------------------------------------------------------------- 46 #include "E3Prefix.h" 47 #include "E3View.h" 48 #include "E3Geometry.h" 49 #include "E3GeometryDisk.h" 50 #include "E3ErrorManager.h" 51 52 53 54 55 56 //============================================================================= 57 // Internal types 58 //----------------------------------------------------------------------------- 59 60 class E3Disk : public E3Geometry // This is a leaf class so no other classes use this, 61 // so it can be here in the .c file rather than in 62 // the .h file, hence all the fields can be public 63 // as nobody should be including this file 64 { 65 Q3_CLASS_ENUMS ( kQ3GeometryTypeDisk, E3Disk, E3Geometry ) 66 public : 67 68 TQ3DiskData instanceData ; 69 70 } ; 71 72 73 74 //============================================================================= 75 // Internal functions 76 //----------------------------------------------------------------------------- 77 // e3geom_disk_new : Disk new method. 78 //----------------------------------------------------------------------------- 79 static TQ3Status 80 e3geom_disk_new(TQ3Object theObject, void *privateData, const void *paramData) 81 { TQ3DiskData *instanceData = (TQ3DiskData *) privateData; 82 const TQ3DiskData *diskData = (const TQ3DiskData *) paramData; 83 TQ3Status qd3dStatus; 84 85 86 87 // Initialise our instance data 88 Q3Memory_Clear(instanceData, sizeof(TQ3DiskData)); 89 90 qd3dStatus = Q3Disk_SetData(theObject, diskData); 91 92 return(qd3dStatus); 93 } 94 95 96 97 98 99 //============================================================================= 100 // e3geom_disk_delete : Disk delete method. 101 //----------------------------------------------------------------------------- 102 static void 103 e3geom_disk_delete(TQ3Object theObject, void *privateData) 104 { TQ3DiskData *instanceData = (TQ3DiskData *) privateData; 105 TQ3Status qd3dStatus; 106 #pragma unused(theObject) 107 108 109 110 // Dispose of our instance data 111 qd3dStatus = Q3Disk_EmptyData(instanceData); 112 } 113 114 115 116 117 118 //============================================================================= 119 // e3geom_disk_duplicate : Disk duplicate method. 120 //----------------------------------------------------------------------------- 121 static TQ3Status 122 e3geom_disk_duplicate(TQ3Object fromObject, const void *fromPrivateData, 123 TQ3Object toObject, void *toPrivateData) 124 { TQ3DiskData *toInstanceData = (TQ3DiskData *) toPrivateData; 125 TQ3Status qd3dStatus; 126 TQ3AttributeSet dupSet; 127 #pragma unused(fromPrivateData) 128 #pragma unused(toObject) 129 130 131 132 // Validate our parameters 133 Q3_REQUIRE_OR_RESULT(Q3_VALID_PTR(fromObject), kQ3Failure); 134 Q3_REQUIRE_OR_RESULT(Q3_VALID_PTR(toPrivateData), kQ3Failure); 135 136 137 138 // Copy the data from fromObject to toObject 139 qd3dStatus = Q3Disk_GetData(fromObject, toInstanceData); 140 141 if ( (qd3dStatus == kQ3Success) && 142 (toInstanceData->diskAttributeSet != NULL) ) 143 { 144 dupSet = Q3Object_Duplicate( toInstanceData->diskAttributeSet ); 145 Q3Object_Dispose( toInstanceData->diskAttributeSet ); 146 toInstanceData->diskAttributeSet = dupSet; 147 if (dupSet == NULL) 148 { 149 qd3dStatus = kQ3Failure; 150 } 151 } 152 153 return(qd3dStatus); 154 } 155 156 157 158 159 160 //============================================================================= 161 // e3geom_disk_calc_point : Compute a point in the disk. 162 //----------------------------------------------------------------------------- 163 static void 164 e3geom_disk_calc_point( const TQ3DiskData *inGeomData, float inSine, float inCosine, 165 float inRadialScale, TQ3Point3D* outPoint ) 166 { 167 TQ3Vector3D theVector; 168 169 Q3Vector3D_Scale(&inGeomData->majorRadius, inRadialScale * inCosine, &theVector); 170 Q3Point3D_Vector3D_Add(&inGeomData->origin, &theVector, outPoint); 171 172 Q3Vector3D_Scale(&inGeomData->minorRadius, inRadialScale * inSine, &theVector); 173 Q3Point3D_Vector3D_Add(outPoint, &theVector, outPoint); 174 } 175 176 177 178 179 180 //============================================================================= 181 // e3geom_disk_cache_new : Disk cache new method. 182 //----------------------------------------------------------------------------- 183 static TQ3Object 184 e3geom_disk_cache_new(TQ3ViewObject theView, TQ3GeometryObject theGeom, const TQ3DiskData *geomData) 185 { float theAngle, deltaAngle, cosAngle, sinAngle; 186 TQ3Uns32 numSides, numPoints, numTriangles, n; 187 TQ3Boolean isPartAngleRange, hasHoleInCenter; 188 float startAngle, endAngle, angleRange; 189 float uMin, uMax, vMin, vMax; 190 TQ3TriMeshAttributeData vertexAttributes[2]; 191 TQ3Vector3D surfaceNormalVector; 192 TQ3SubdivisionStyleData subdivisionData; 193 TQ3TriMeshTriangleData *theTriangles; 194 TQ3TriMeshData triMeshData; 195 TQ3Vector3D *theNormals; 196 float crossLength; 197 TQ3GeometryObject theTriMesh; 198 TQ3Point3D *thePoints; 199 TQ3Status qd3dStatus; 200 TQ3GroupObject theGroup; 201 TQ3Param2D *theUVs; 202 203 204 205 // Get the UV limits and make sure they are valid. 206 // These are for specifying partial disks, and have little to do 207 // with surface UV coordinates. 208 uMin = E3Num_Clamp(geomData->uMin, 0.0f, 1.0f); 209 uMax = E3Num_Clamp(geomData->uMax, 0.0f, 1.0f); 210 vMin = E3Num_Clamp(geomData->vMin, 0.0f, 1.0f); 211 vMax = E3Num_Clamp(geomData->vMax, 0.0f, 1.0f); 212 // It is possible for uMin to be greater than uMax, so that 213 // we can specify which way to wrap around the circle. 214 // But it doesn't make sense for vMin to be greater than vMax. 215 if (vMin > vMax) 216 E3Float_Swap( vMin, vMax ); 217 hasHoleInCenter = (vMin > kQ3RealZero)? kQ3True : kQ3False; 218 219 220 221 // Turn the u limits into an angle range in radians. 222 startAngle = uMin * kQ32Pi; 223 endAngle = uMax * kQ32Pi; 224 if (startAngle > endAngle) 225 startAngle -= kQ32Pi; 226 angleRange = endAngle - startAngle; 227 isPartAngleRange = E3Float_Abs( angleRange - kQ32Pi ) > kQ3RealZero? 228 kQ3True : kQ3False; 229 230 231 232 // Get the subdivision style, to figure out how many sides we should have. 233 numSides = 10; 234 qd3dStatus = Q3View_GetSubdivisionStyleState(theView, &subdivisionData); 235 if (qd3dStatus == kQ3Success) 236 { 237 switch (subdivisionData.method) { 238 case kQ3SubdivisionMethodConstant: 239 // For a disk, parameter c1 is the number of sides and c2 is unused 240 numSides = (TQ3Uns32) subdivisionData.c1; 241 break; 242 243 case kQ3SubdivisionMethodWorldSpace: 244 // keep the length of any side less than or equal to c1 245 { 246 TQ3Matrix4x4 localToWorld; 247 TQ3Vector3D bigRadius, workVec; 248 249 // Find the longer of the two radius vectors. 250 bigRadius = geomData->majorRadius; 251 if (Q3Vector3D_LengthSquared( &geomData->majorRadius ) < 252 Q3Vector3D_LengthSquared( &geomData->minorRadius ) ) 253 { 254 bigRadius = geomData->minorRadius; 255 } 256 257 // divide the circumference by c1 258 Q3View_GetLocalToWorldMatrixState( theView, &localToWorld ); 259 Q3Vector3D_Transform( &bigRadius, &localToWorld, &workVec ); 260 numSides = (TQ3Uns32) ((kQ32Pi * Q3Vector3D_Length(&workVec)) 261 / subdivisionData.c1); 262 } 263 break; 264 265 case kQ3SubdivisionMethodScreenSpace: 266 // Not implemented 267 break; 268 269 case kQ3SubdivisionMethodSize32: 270 default: 271 Q3_ASSERT(!"Unknown subdivision method"); 272 break; 273 } 274 } 275 numSides = E3Num_Clamp(numSides, 3, 256); 276 277 278 279 // For a solid disk, we need one triangle for each side, but if there is a hole 280 // in the center, we need two triangles for each side. 281 // If the disk is not on the full angle range, we need extra points for the 282 // boundary. 283 if (hasHoleInCenter) 284 { 285 numTriangles = numSides * 2; 286 numPoints = numSides * 2; 287 if (isPartAngleRange == kQ3True) 288 numPoints += 2; 289 } 290 else // solid 291 { 292 numTriangles = numSides; 293 numPoints = numSides + 1; // + 1 for center 294 if (isPartAngleRange == kQ3True) 295 numPoints += 1; 296 } 297 298 299 300 // Allocate the memory we need for the TriMesh data 301 thePoints = (TQ3Point3D *) Q3Memory_Allocate(numPoints * sizeof(TQ3Point3D)); 302 theNormals = (TQ3Vector3D *) Q3Memory_Allocate(numPoints * sizeof(TQ3Vector3D)); 303 theUVs = (TQ3Param2D *) Q3Memory_Allocate(numPoints * sizeof(TQ3Param2D)); 304 theTriangles = (TQ3TriMeshTriangleData *) Q3Memory_Allocate(numTriangles * sizeof(TQ3TriMeshTriangleData)); 305 306 if (thePoints == NULL || theNormals == NULL || theUVs == NULL || theTriangles == NULL) 307 { 308 Q3Memory_Free(&thePoints); 309 Q3Memory_Free(&theNormals); 310 Q3Memory_Free(&theUVs); 311 Q3Memory_Free(&theTriangles); 312 313 return(NULL); 314 } 315 316 317 318 // Define the sides, as a cosine/sine combination of major and minor radius vectors 319 deltaAngle = angleRange / (float) numSides; 320 for (n = 0, theAngle = startAngle; n < numSides; ++n, theAngle += deltaAngle) 321 { 322 // Figure out where we are 323 cosAngle = (float) cos(theAngle); 324 sinAngle = (float) sin(theAngle); 325 326 327 // Set up the points 328 if (hasHoleInCenter) 329 { 330 e3geom_disk_calc_point( geomData, sinAngle, cosAngle, vMax, &thePoints[2*n] ); 331 e3geom_disk_calc_point( geomData, sinAngle, cosAngle, vMin, &thePoints[2*n+1] ); 332 } 333 else 334 { 335 e3geom_disk_calc_point( geomData, sinAngle, cosAngle, vMax, &thePoints[n] ); 336 } 337 338 339 // Set up the surface UV coordinates 340 if (hasHoleInCenter) 341 { 342 theUVs[2*n].u = (vMax * cosAngle + 1.0f) / 2.0f; 343 theUVs[2*n].v = (vMax * sinAngle + 1.0f) / 2.0f; 344 theUVs[2*n+1].u = (vMin * cosAngle + 1.0f) / 2.0f; 345 theUVs[2*n+1].v = (vMin * sinAngle + 1.0f) / 2.0f; 346 } 347 else 348 { 349 theUVs[n].u = (vMax * cosAngle + 1.0f) / 2.0f; 350 theUVs[n].v = (vMax * sinAngle + 1.0f) / 2.0f; 351 } 352 353 354 // Set up the triangles 355 if (hasHoleInCenter) 356 { 357 if (isPartAngleRange) 358 { 359 theTriangles[2*n].pointIndices[0] = 2*n + 1; 360 theTriangles[2*n].pointIndices[1] = 2*n; 361 theTriangles[2*n].pointIndices[2] = 2*n + 2; 362 363 theTriangles[2*n+1].pointIndices[0] = 2*n + 1; 364 theTriangles[2*n+1].pointIndices[1] = 2*n + 2; 365 theTriangles[2*n+1].pointIndices[2] = 2*n + 3; 366 } 367 else 368 { 369 theTriangles[2*n].pointIndices[0] = 2*n + 1; 370 theTriangles[2*n].pointIndices[1] = 2*n; 371 theTriangles[2*n].pointIndices[2] = (2*n + 2) % (2*numSides); 372 373 theTriangles[2*n+1].pointIndices[0] = 2*n + 1; 374 theTriangles[2*n+1].pointIndices[1] = (2*n + 2) % (2*numSides); 375 theTriangles[2*n+1].pointIndices[2] = (2*n + 3) % (2*numSides); 376 } 377 } 378 else 379 { 380 if (isPartAngleRange) 381 { 382 theTriangles[n].pointIndices[0] = numSides + 1; 383 theTriangles[n].pointIndices[1] = n; 384 theTriangles[n].pointIndices[2] = n + 1; 385 } 386 else 387 { 388 theTriangles[n].pointIndices[0] = numSides; 389 theTriangles[n].pointIndices[1] = n; 390 theTriangles[n].pointIndices[2] = (n + 1) % numSides; 391 } 392 } 393 } 394 395 396 397 // Finish with center and/or boundary 398 if (isPartAngleRange) 399 { 400 cosAngle = (float) cos(theAngle); 401 sinAngle = (float) sin(theAngle); 402 if (hasHoleInCenter) 403 { 404 e3geom_disk_calc_point( geomData, sinAngle, cosAngle, vMax, 405 &thePoints[2*numSides] ); 406 e3geom_disk_calc_point( geomData, sinAngle, cosAngle, vMin, 407 &thePoints[2*numSides+1] ); 408 theUVs[2*numSides].u = (vMax * cosAngle + 1.0f) / 2.0f; 409 theUVs[2*numSides].v = (vMax * sinAngle + 1.0f) / 2.0f; 410 theUVs[2*numSides+1].u = (vMin * cosAngle + 1.0f) / 2.0f; 411 theUVs[2*numSides+1].v = (vMin * sinAngle + 1.0f) / 2.0f; 412 } 413 else 414 { 415 e3geom_disk_calc_point( geomData, sinAngle, cosAngle, vMax, 416 &thePoints[numSides] ); 417 thePoints[numSides+1] = geomData->origin; 418 theUVs[numSides].u = (vMax * cosAngle + 1.0f) / 2.0f; 419 theUVs[numSides].v = (vMax * sinAngle + 1.0f) / 2.0f; 420 theUVs[numSides+1].u = 0.5f; 421 theUVs[numSides+1].v = 0.5f; 422 } 423 } 424 else 425 { 426 if (hasHoleInCenter == kQ3False) 427 { 428 thePoints[numSides] = geomData->origin; 429 theUVs[numSides].u = 0.5f; 430 theUVs[numSides].v = 0.5f; 431 } 432 } 433 434 435 436 // Surface normal is the cross product of the majorRadius and minorRadius 437 Q3Vector3D_Cross(&geomData->majorRadius, &geomData->minorRadius, &surfaceNormalVector); 438 crossLength = Q3Vector3D_Length( &surfaceNormalVector ); 439 if (crossLength <= kQ3RealZero) 440 { 441 surfaceNormalVector.x = 1.0f; // arbitrary 442 E3ErrorManager_PostError( kQ3ErrorDegenerateGeometry, kQ3False ); 443 } 444 else 445 { 446 Q3Vector3D_Scale( &surfaceNormalVector, 1.0f/crossLength, &surfaceNormalVector ); 447 } 448 449 for (n = 0; n < numPoints; ++n) 450 theNormals[ n ] = surfaceNormalVector; 451 452 453 454 // Initialise the vertex attributes 455 vertexAttributes[0].attributeType = kQ3AttributeTypeNormal; 456 vertexAttributes[0].data = theNormals; 457 vertexAttributes[0].attributeUseArray = NULL; 458 459 vertexAttributes[1].attributeType = kQ3AttributeTypeSurfaceUV; 460 vertexAttributes[1].data = theUVs; 461 vertexAttributes[1].attributeUseArray = NULL; 462 463 464 465 // Initialise the TriMesh data 466 triMeshData.numPoints = numPoints; 467 triMeshData.points = thePoints; 468 triMeshData.numTriangles = numTriangles; 469 triMeshData.triangles = theTriangles; 470 triMeshData.numTriangleAttributeTypes = 0; 471 triMeshData.triangleAttributeTypes = NULL; 472 triMeshData.numEdges = 0; 473 triMeshData.edges = NULL; 474 triMeshData.numEdgeAttributeTypes = 0; 475 triMeshData.edgeAttributeTypes = NULL; 476 triMeshData.numVertexAttributeTypes = 2; 477 triMeshData.vertexAttributeTypes = vertexAttributes; 478 triMeshData.triMeshAttributeSet = geomData->diskAttributeSet; 479 480 Q3BoundingBox_SetFromPoints3D(&triMeshData.bBox, triMeshData.points, triMeshData.numPoints, sizeof(TQ3Point3D)); 481 482 483 484 // Create the TriMesh 485 theTriMesh = Q3TriMesh_New(&triMeshData); 486 theGroup = E3TriMesh_BuildOrientationGroup(theTriMesh, kQ3OrientationStyleCounterClockwise); 487 488 489 490 // Clean up 491 Q3Memory_Free(&thePoints); 492 Q3Memory_Free(&theNormals); 493 Q3Memory_Free(&theUVs); 494 Q3Memory_Free(&theTriangles); 495 496 497 498 // Return the cached geometry 499 return(theGroup); 500 } 501 502 503 504 505 506 507 //============================================================================= 508 // e3geom_disk_get_attribute : Disk get attribute set pointer. 509 //----------------------------------------------------------------------------- 510 static TQ3AttributeSet * 511 e3geom_disk_get_attribute ( E3Disk* disk ) 512 { 513 // Return the address of the geometry attribute set 514 return & disk->instanceData.diskAttributeSet ; 515 } 516 517 518 519 520 521 //============================================================================= 522 // e3geom_disk_metahandler : Disk metahandler. 523 //----------------------------------------------------------------------------- 524 static TQ3XFunctionPointer 525 e3geom_disk_metahandler(TQ3XMethodType methodType) 526 { TQ3XFunctionPointer theMethod = NULL; 527 528 529 530 // Return our methods 531 switch (methodType) { 532 case kQ3XMethodTypeObjectNew: 533 theMethod = (TQ3XFunctionPointer) e3geom_disk_new; 534 break; 535 536 case kQ3XMethodTypeObjectDelete: 537 theMethod = (TQ3XFunctionPointer) e3geom_disk_delete; 538 break; 539 540 case kQ3XMethodTypeObjectDuplicate: 541 theMethod = (TQ3XFunctionPointer) e3geom_disk_duplicate; 542 break; 543 544 case kQ3XMethodTypeGeomCacheNew: 545 theMethod = (TQ3XFunctionPointer) e3geom_disk_cache_new; 546 break; 547 548 case kQ3XMethodTypeGeomGetAttribute: 549 theMethod = (TQ3XFunctionPointer) e3geom_disk_get_attribute; 550 break; 551 552 case kQ3XMethodTypeGeomUsesSubdivision: 553 theMethod = (TQ3XFunctionPointer) kQ3True; 554 break; 555 } 556 557 return(theMethod); 558 } 559 560 561 562 563 564 //============================================================================= 565 // Public functions 566 //----------------------------------------------------------------------------- 567 // E3GeometryDisk_RegisterClass : Register the class. 568 //----------------------------------------------------------------------------- 569 #pragma mark - 570 TQ3Status 571 E3GeometryDisk_RegisterClass(void) 572 { 573 // Register the class 574 return Q3_REGISTER_CLASS ( kQ3ClassNameGeometryDisk, 575 e3geom_disk_metahandler, 576 E3Disk ) ; 577 } 578 579 580 581 582 583 //============================================================================= 584 // E3GeometryDisk_UnregisterClass : Unregister the class. 585 //----------------------------------------------------------------------------- 586 TQ3Status 587 E3GeometryDisk_UnregisterClass(void) 588 { TQ3Status qd3dStatus; 589 590 591 592 // Unregister the class 593 qd3dStatus = E3ClassTree::UnregisterClass(kQ3GeometryTypeDisk, kQ3True); 594 595 return(qd3dStatus); 596 } 597 598 599 600 601 602 //============================================================================= 603 // E3Disk_New : Create a disk object. 604 //----------------------------------------------------------------------------- 605 #pragma mark - 606 TQ3GeometryObject 607 E3Disk_New(const TQ3DiskData *diskData) 608 { 609 TQ3Object theObject; 610 611 612 if (diskData == NULL) 613 { 614 TQ3DiskData defaultDiskData = { 615 { 0.0f, 0.0f, 0.0f }, 616 { 1.0f, 0.0f, 0.0f }, 617 { 0.0f, 1.0f, 0.0f }, 618 0.0f, 1.0f, 0.0f, 1.0f, 619 NULL 620 }; 621 theObject = E3ClassTree::CreateInstance ( kQ3GeometryTypeDisk, kQ3False, &defaultDiskData ) ; 622 } 623 else 624 theObject = E3ClassTree::CreateInstance ( kQ3GeometryTypeDisk, kQ3False, diskData ) ; 625 626 627 return (theObject); 628 } 629 630 631 632 633 634 //============================================================================= 635 // E3Disk_Submit : Submit a disk. 636 //----------------------------------------------------------------------------- 637 TQ3Status 638 E3Disk_Submit(const TQ3DiskData *diskData, TQ3ViewObject theView) 639 { TQ3Status qd3dStatus; 640 641 642 643 // Submit the geometry 644 qd3dStatus = E3View_SubmitImmediate(theView, kQ3GeometryTypeDisk, diskData); 645 return(qd3dStatus); 646 } 647 648 649 650 651 652 //============================================================================= 653 // E3Disk_SetData : Set the data for a disk object. 654 //----------------------------------------------------------------------------- 655 TQ3Status 656 E3Disk_SetData(TQ3GeometryObject theDisk, const TQ3DiskData *diskData) 657 { 658 E3Disk* disk = (E3Disk*) theDisk ; 659 660 // Set the data 661 disk->instanceData.origin = diskData->origin ; 662 disk->instanceData.majorRadius = diskData->majorRadius ; 663 disk->instanceData.minorRadius = diskData->minorRadius ; 664 disk->instanceData.uMin = diskData->uMin ; 665 disk->instanceData.uMax = diskData->uMax ; 666 disk->instanceData.vMin = diskData->vMin ; 667 disk->instanceData.vMax = diskData->vMax ; 668 669 E3Shared_Replace ( &disk->instanceData.diskAttributeSet, diskData->diskAttributeSet ) ; 670 671 Q3Shared_Edited ( disk ) ; 672 673 return kQ3Success ; 674 } 675 676 677 678 679 680 //============================================================================= 681 // E3Disk_GetData : Get the data for a disk object. 682 //----------------------------------------------------------------------------- 683 TQ3Status 684 E3Disk_GetData(TQ3GeometryObject theDisk, TQ3DiskData *diskData) 685 { 686 E3Disk* disk = (E3Disk*) theDisk ; 687 688 // Get the data 689 diskData->origin = disk->instanceData.origin ; 690 diskData->majorRadius = disk->instanceData.majorRadius ; 691 diskData->minorRadius = disk->instanceData.minorRadius ; 692 diskData->uMin = disk->instanceData.uMin ; 693 diskData->uMax = disk->instanceData.uMax ; 694 diskData->vMin = disk->instanceData.vMin ; 695 diskData->vMax = disk->instanceData.vMax ; 696 697 E3Shared_Acquire ( & diskData->diskAttributeSet, disk->instanceData.diskAttributeSet ) ; 698 699 return kQ3Success ; 700 } 701 702 703 704 705 706 //============================================================================= 707 // E3Disk_EmptyData : Empty the data for a disk object. 708 //----------------------------------------------------------------------------- 709 TQ3Status 710 E3Disk_EmptyData(TQ3DiskData *diskData) 711 { 712 713 714 // Release the data 715 Q3Object_CleanDispose(&diskData->diskAttributeSet); 716 717 return(kQ3Success); 718 } 719 720 721 722 723 724 //============================================================================= 725 // E3Disk_SetOrigin : Set the origin for a disk object. 726 //----------------------------------------------------------------------------- 727 TQ3Status 728 E3Disk_SetOrigin(TQ3GeometryObject theDisk, const TQ3Point3D *origin) 729 { 730 E3Disk* disk = (E3Disk*) theDisk ; 731 732 // Set the origin 733 disk->instanceData.origin = *origin ; 734 735 Q3Shared_Edited ( disk ) ; 736 737 return kQ3Success ; 738 } 739 740 741 742 743 744 //============================================================================= 745 // E3Disk_SetMajorRadius : Set the major radius for a disk object. 746 //----------------------------------------------------------------------------- 747 TQ3Status 748 E3Disk_SetMajorRadius(TQ3GeometryObject theDisk, const TQ3Vector3D *majorRadius) 749 { 750 E3Disk* disk = (E3Disk*) theDisk ; 751 752 // Set the major radius 753 disk->instanceData.majorRadius = *majorRadius ; 754 755 Q3Shared_Edited ( disk ) ; 756 757 return kQ3Success ; 758 } 759 760 761 762 763 764 //============================================================================= 765 // E3Disk_SetMinorRadius : Set the minor radius for a disk object. 766 //----------------------------------------------------------------------------- 767 TQ3Status 768 E3Disk_SetMinorRadius(TQ3GeometryObject theDisk, const TQ3Vector3D *minorRadius) 769 { 770 E3Disk* disk = (E3Disk*) theDisk ; 771 772 // Set the minor radius 773 disk->instanceData.minorRadius = *minorRadius ; 774 775 Q3Shared_Edited ( disk ) ; 776 777 return kQ3Success ; 778 } 779 780 781 782 783 784 //============================================================================= 785 // E3Disk_GetOrigin : Get the origin for a disk object. 786 //----------------------------------------------------------------------------- 787 TQ3Status 788 E3Disk_GetOrigin(TQ3GeometryObject theDisk, TQ3Point3D *origin) 789 { 790 E3Disk* disk = (E3Disk*) theDisk ; 791 792 // Get the origin 793 *origin = disk->instanceData.origin; 794 795 return kQ3Success ; 796 } 797 798 799 800 801 802 //============================================================================= 803 // E3Disk_GetMajorRadius : Get the major radius for a disk object. 804 //----------------------------------------------------------------------------- 805 TQ3Status 806 E3Disk_GetMajorRadius(TQ3GeometryObject theDisk, TQ3Vector3D *majorRadius) 807 { 808 E3Disk* disk = (E3Disk*) theDisk ; 809 810 // Get the major radius 811 *majorRadius = disk->instanceData.majorRadius ; 812 813 return kQ3Success ; 814 } 815 816 817 818 819 820 //============================================================================= 821 // E3Disk_GetMinorRadius : Get the minor radius for a disk object. 822 //----------------------------------------------------------------------------- 823 TQ3Status 824 E3Disk_GetMinorRadius(TQ3GeometryObject theDisk, TQ3Vector3D *minorRadius) 825 { 826 E3Disk* disk = (E3Disk*) theDisk ; 827 828 // Get the minor radius 829 *minorRadius = disk->instanceData.minorRadius ; 830 831 return kQ3Success ; 832 } 833