| 1 | // Created on: 2001-07-02 |
| 2 | // Created by: Mathias BOSSHARD |
| 3 | // Copyright (c) 2001-2014 OPEN CASCADE SAS |
| 4 | // |
| 5 | // This file is part of Open CASCADE Technology software library. |
| 6 | // |
| 7 | // This library is free software; you can redistribute it and/or modify it under |
| 8 | // the terms of the GNU Lesser General Public License version 2.1 as published |
| 9 | // by the Free Software Foundation, with special exception defined in the file |
| 10 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
| 11 | // distribution for complete text of the license and disclaimer of any warranty. |
| 12 | // |
| 13 | // Alternatively, this file may be used under the terms of Open CASCADE |
| 14 | // commercial license or contractual agreement. |
| 15 | |
| 16 | #include <AIS_TexturedShape.hxx> |
| 17 | |
| 18 | #include <AIS_GraphicTool.hxx> |
| 19 | #include <AIS_InteractiveContext.hxx> |
| 20 | #include <BRepTools.hxx> |
| 21 | #include <gp_Pnt2d.hxx> |
| 22 | #include <Graphic3d_AspectFillArea3d.hxx> |
| 23 | #include <Graphic3d_Group.hxx> |
| 24 | #include <Graphic3d_StructureManager.hxx> |
| 25 | #include <Graphic3d_Texture2Dmanual.hxx> |
| 26 | #include <Message.hxx> |
| 27 | #include <Message_Messenger.hxx> |
| 28 | #include <Precision.hxx> |
| 29 | #include <Prs3d_Drawer.hxx> |
| 30 | #include <Prs3d_Presentation.hxx> |
| 31 | #include <PrsMgr_ModedPresentation.hxx> |
| 32 | #include <Prs3d_Root.hxx> |
| 33 | #include <Prs3d_LineAspect.hxx> |
| 34 | #include <Prs3d_ShadingAspect.hxx> |
| 35 | #include <PrsMgr_PresentationManager3d.hxx> |
| 36 | #include <Standard_ErrorHandler.hxx> |
| 37 | #include <StdPrs_BndBox.hxx> |
| 38 | #include <StdPrs_ShadedShape.hxx> |
| 39 | #include <StdPrs_ToolTriangulatedShape.hxx> |
| 40 | #include <StdPrs_WFShape.hxx> |
| 41 | #include <TopExp_Explorer.hxx> |
| 42 | |
| 43 | |
| 44 | IMPLEMENT_STANDARD_RTTIEXT(AIS_TexturedShape,AIS_Shape) |
| 45 | |
| 46 | //======================================================================= |
| 47 | //function : AIS_TexturedShape |
| 48 | //purpose : |
| 49 | //======================================================================= |
| 50 | AIS_TexturedShape::AIS_TexturedShape (const TopoDS_Shape& theShape) |
| 51 | : AIS_Shape (theShape), |
| 52 | myPredefTexture (Graphic3d_NameOfTexture2D(0)), |
| 53 | myToMapTexture (Standard_True), |
| 54 | myModulate (Standard_True), |
| 55 | myUVOrigin (0.0, 0.0), |
| 56 | myIsCustomOrigin (Standard_True), |
| 57 | myUVRepeat (1.0, 1.0), |
| 58 | myToRepeat (Standard_True), |
| 59 | myUVScale (1.0, 1.0), |
| 60 | myToScale (Standard_True), |
| 61 | myToShowTriangles (Standard_False) |
| 62 | { |
| 63 | } |
| 64 | |
| 65 | //======================================================================= |
| 66 | //function : SetTextureFileName |
| 67 | //purpose : |
| 68 | //======================================================================= |
| 69 | void AIS_TexturedShape::SetTextureFileName (const TCollection_AsciiString& theTextureFileName) |
| 70 | { |
| 71 | myTexturePixMap.Nullify(); |
| 72 | |
| 73 | if (theTextureFileName.IsIntegerValue()) |
| 74 | { |
| 75 | const Standard_Integer aValue = theTextureFileName.IntegerValue(); |
| 76 | if (aValue < Graphic3d_Texture2D::NumberOfTextures() |
| 77 | && aValue >= 0) |
| 78 | { |
| 79 | myPredefTexture = Graphic3d_NameOfTexture2D (aValue); |
| 80 | } |
| 81 | else |
| 82 | { |
| 83 | Message::DefaultMessenger()->Send (TCollection_AsciiString ("Error: texture with ID ") + theTextureFileName |
| 84 | + " is undefined! Texture 0 will be used instead.", Message_Fail); |
| 85 | myPredefTexture = Graphic3d_NameOfTexture2D (0); |
| 86 | } |
| 87 | myTextureFile = ""; |
| 88 | } |
| 89 | else |
| 90 | { |
| 91 | myTextureFile = theTextureFileName; |
| 92 | myPredefTexture = Graphic3d_NOT_2D_UNKNOWN; |
| 93 | } |
| 94 | } |
| 95 | |
| 96 | //======================================================================= |
| 97 | //function : SetTexturePixMap |
| 98 | //purpose : |
| 99 | //======================================================================= |
| 100 | void AIS_TexturedShape::SetTexturePixMap (const Handle(Image_PixMap)& theTexturePixMap) |
| 101 | { |
| 102 | myTextureFile = ""; |
| 103 | myPredefTexture = Graphic3d_NOT_2D_UNKNOWN; |
| 104 | myTexturePixMap = theTexturePixMap; |
| 105 | } |
| 106 | |
| 107 | //======================================================================= |
| 108 | //function : SetTextureRepeat |
| 109 | //purpose : |
| 110 | //======================================================================= |
| 111 | |
| 112 | void AIS_TexturedShape::SetTextureRepeat (const Standard_Boolean theToRepeat, |
| 113 | const Standard_Real theURepeat, |
| 114 | const Standard_Real theVRepeat) |
| 115 | { |
| 116 | myToRepeat = theToRepeat; |
| 117 | myUVRepeat.SetCoord (theURepeat, theVRepeat); |
| 118 | } |
| 119 | |
| 120 | //======================================================================= |
| 121 | //function : SetTextureMapOn |
| 122 | //purpose : |
| 123 | //======================================================================= |
| 124 | |
| 125 | void AIS_TexturedShape::SetTextureMapOn() |
| 126 | { |
| 127 | myToMapTexture = Standard_True; |
| 128 | } |
| 129 | |
| 130 | //======================================================================= |
| 131 | //function : SetTextureMapOff |
| 132 | //purpose : |
| 133 | //======================================================================= |
| 134 | |
| 135 | void AIS_TexturedShape::SetTextureMapOff() |
| 136 | { |
| 137 | myToMapTexture = Standard_False; |
| 138 | } |
| 139 | |
| 140 | //======================================================================= |
| 141 | //function : SetTextureOrigin |
| 142 | //purpose : |
| 143 | //======================================================================= |
| 144 | |
| 145 | void AIS_TexturedShape::SetTextureOrigin (const Standard_Boolean theToSetTextureOrigin, |
| 146 | const Standard_Real theUOrigin, |
| 147 | const Standard_Real theVOrigin) |
| 148 | { |
| 149 | myIsCustomOrigin = theToSetTextureOrigin; |
| 150 | myUVOrigin.SetCoord (theUOrigin, theVOrigin); |
| 151 | } |
| 152 | |
| 153 | //======================================================================= |
| 154 | //function : SetTextureScale |
| 155 | //purpose : |
| 156 | //======================================================================= |
| 157 | |
| 158 | void AIS_TexturedShape::SetTextureScale (const Standard_Boolean theToSetTextureScale, |
| 159 | const Standard_Real theScaleU, |
| 160 | const Standard_Real theScaleV) |
| 161 | { |
| 162 | myToScale = theToSetTextureScale; |
| 163 | myUVScale.SetCoord (theScaleU, theScaleV); |
| 164 | } |
| 165 | |
| 166 | //======================================================================= |
| 167 | //function : ShowTriangles |
| 168 | //purpose : |
| 169 | //======================================================================= |
| 170 | |
| 171 | void AIS_TexturedShape::ShowTriangles (const Standard_Boolean theToShowTriangles) |
| 172 | { |
| 173 | myToShowTriangles = theToShowTriangles; |
| 174 | } |
| 175 | |
| 176 | //======================================================================= |
| 177 | //function : EnableTextureModulate |
| 178 | //purpose : |
| 179 | //======================================================================= |
| 180 | |
| 181 | void AIS_TexturedShape::EnableTextureModulate() |
| 182 | { |
| 183 | myModulate = Standard_True; |
| 184 | } |
| 185 | |
| 186 | //======================================================================= |
| 187 | //function : DisableTextureModulate |
| 188 | //purpose : |
| 189 | //======================================================================= |
| 190 | |
| 191 | void AIS_TexturedShape::DisableTextureModulate() |
| 192 | { |
| 193 | myModulate = Standard_False; |
| 194 | } |
| 195 | |
| 196 | //======================================================================= |
| 197 | //function : SetColor |
| 198 | //purpose : |
| 199 | //======================================================================= |
| 200 | |
| 201 | void AIS_TexturedShape::SetColor (const Quantity_Color& theColor) |
| 202 | { |
| 203 | AIS_Shape::SetColor (theColor); |
| 204 | |
| 205 | for (Standard_Integer aPrsIt = 1; aPrsIt <= Presentations().Length(); ++aPrsIt) |
| 206 | { |
| 207 | const PrsMgr_ModedPresentation& aPrsModed = Presentations().Value (aPrsIt); |
| 208 | |
| 209 | if (aPrsModed.Mode() != 3) |
| 210 | continue; |
| 211 | |
| 212 | updateAttributes (aPrsModed.Presentation()->Presentation()); |
| 213 | } |
| 214 | } |
| 215 | |
| 216 | //======================================================================= |
| 217 | //function : UnsetColor |
| 218 | //purpose : |
| 219 | //======================================================================= |
| 220 | |
| 221 | void AIS_TexturedShape::UnsetColor() |
| 222 | { |
| 223 | AIS_Shape::UnsetColor(); |
| 224 | |
| 225 | for (Standard_Integer aPrsIt = 1; aPrsIt <= Presentations().Length(); ++aPrsIt) |
| 226 | { |
| 227 | const PrsMgr_ModedPresentation& aPrsModed = Presentations().Value (aPrsIt); |
| 228 | |
| 229 | if (aPrsModed.Mode() != 3) |
| 230 | continue; |
| 231 | |
| 232 | Handle(Prs3d_Presentation) aPrs = aPrsModed.Presentation()->Presentation(); |
| 233 | Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup (aPrs); |
| 234 | |
| 235 | Handle(Graphic3d_AspectFillArea3d) anAreaAsp = myDrawer->Link()->ShadingAspect()->Aspect(); |
| 236 | Handle(Graphic3d_AspectLine3d) aLineAsp = myDrawer->Link()->LineAspect()->Aspect(); |
| 237 | Quantity_Color aColor; |
| 238 | AIS_GraphicTool::GetInteriorColor (myDrawer->Link(), aColor); |
| 239 | anAreaAsp->SetInteriorColor (aColor); |
| 240 | // Check if aspect of given type is set for the group, |
| 241 | // because setting aspect for group with no already set aspect |
| 242 | // can lead to loss of presentation data |
| 243 | if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_FILL_AREA)) |
| 244 | { |
| 245 | aGroup->SetGroupPrimitivesAspect (anAreaAsp); |
| 246 | } |
| 247 | if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_LINE)) |
| 248 | { |
| 249 | aGroup->SetGroupPrimitivesAspect (aLineAsp); |
| 250 | } |
| 251 | |
| 252 | updateAttributes (aPrs); |
| 253 | } |
| 254 | } |
| 255 | |
| 256 | //======================================================================= |
| 257 | //function : SetMaterial |
| 258 | //purpose : |
| 259 | //======================================================================= |
| 260 | |
| 261 | void AIS_TexturedShape::SetMaterial (const Graphic3d_MaterialAspect& theMat) |
| 262 | { |
| 263 | AIS_Shape::SetMaterial (theMat); |
| 264 | |
| 265 | for (Standard_Integer aPrsIt = 1; aPrsIt <= Presentations().Length(); ++aPrsIt) |
| 266 | { |
| 267 | const PrsMgr_ModedPresentation& aPrsModed = Presentations().Value (aPrsIt); |
| 268 | |
| 269 | if (aPrsModed.Mode() != 3) |
| 270 | continue; |
| 271 | |
| 272 | updateAttributes (aPrsModed.Presentation()->Presentation()); |
| 273 | } |
| 274 | } |
| 275 | |
| 276 | //======================================================================= |
| 277 | //function : UnsetMaterial |
| 278 | //purpose : |
| 279 | //======================================================================= |
| 280 | void AIS_TexturedShape::UnsetMaterial() |
| 281 | { |
| 282 | AIS_Shape::UnsetMaterial(); |
| 283 | |
| 284 | for (Standard_Integer aPrsIt = 1; aPrsIt <= Presentations().Length(); ++aPrsIt) |
| 285 | { |
| 286 | const PrsMgr_ModedPresentation& aPrsModed = Presentations().Value (aPrsIt); |
| 287 | |
| 288 | if (aPrsModed.Mode() != 3) |
| 289 | continue; |
| 290 | |
| 291 | updateAttributes (aPrsModed.Presentation()->Presentation()); |
| 292 | } |
| 293 | } |
| 294 | |
| 295 | //======================================================================= |
| 296 | //function : UpdateAttributes |
| 297 | //purpose : |
| 298 | //======================================================================= |
| 299 | |
| 300 | void AIS_TexturedShape::UpdateAttributes() |
| 301 | { |
| 302 | updateAttributes (Presentation()); |
| 303 | } |
| 304 | |
| 305 | //======================================================================= |
| 306 | //function : updateAttributes |
| 307 | //purpose : |
| 308 | //======================================================================= |
| 309 | |
| 310 | void AIS_TexturedShape::updateAttributes (const Handle(Prs3d_Presentation)& thePrs) |
| 311 | { |
| 312 | myAspect = new Graphic3d_AspectFillArea3d (*myDrawer->ShadingAspect()->Aspect()); |
| 313 | if (HasPolygonOffsets()) |
| 314 | { |
| 315 | Standard_Integer aMode; |
| 316 | Standard_ShortReal aFactor, aUnits; |
| 317 | PolygonOffsets (aMode, aFactor, aUnits); |
| 318 | myAspect->SetPolygonOffsets (aMode, aFactor, aUnits); |
| 319 | } |
| 320 | |
| 321 | Standard_Boolean hasTexture = Standard_False; |
| 322 | if (myToMapTexture) |
| 323 | { |
| 324 | TCollection_AsciiString aTextureDesc; |
| 325 | if (!myTexturePixMap.IsNull()) |
| 326 | { |
| 327 | myTexture = new Graphic3d_Texture2Dmanual (myTexturePixMap); |
| 328 | aTextureDesc = " (custom image)"; |
| 329 | } |
| 330 | else if (myPredefTexture != Graphic3d_NOT_2D_UNKNOWN) |
| 331 | { |
| 332 | myTexture = new Graphic3d_Texture2Dmanual (myPredefTexture); |
| 333 | aTextureDesc = TCollection_AsciiString(" (predefined texture ") + myTexture->GetId() + ")"; |
| 334 | } |
| 335 | else |
| 336 | { |
| 337 | myTexture = new Graphic3d_Texture2Dmanual (myTextureFile.ToCString()); |
| 338 | aTextureDesc = TCollection_AsciiString(" (") + myTextureFile + ")"; |
| 339 | } |
| 340 | |
| 341 | if (myModulate) |
| 342 | { |
| 343 | myTexture->EnableModulate(); |
| 344 | } |
| 345 | else |
| 346 | { |
| 347 | myTexture->DisableModulate(); |
| 348 | } |
| 349 | |
| 350 | if (myTexture->IsDone()) |
| 351 | { |
| 352 | hasTexture = Standard_True; |
| 353 | } |
| 354 | else |
| 355 | { |
| 356 | Message::DefaultMessenger()->Send (TCollection_AsciiString ("Error: texture can not be loaded ") + aTextureDesc, Message_Fail); |
| 357 | } |
| 358 | } |
| 359 | |
| 360 | myAspect->SetTextureMap (myTexture); |
| 361 | if (hasTexture) |
| 362 | { |
| 363 | myAspect->SetTextureMapOn(); |
| 364 | } |
| 365 | else |
| 366 | { |
| 367 | myAspect->SetTextureMapOff(); |
| 368 | } |
| 369 | |
| 370 | if (myToShowTriangles) |
| 371 | { |
| 372 | myAspect->SetEdgeOn(); |
| 373 | } |
| 374 | else |
| 375 | { |
| 376 | myAspect->SetEdgeOff(); |
| 377 | } |
| 378 | |
| 379 | // Go through all groups to change fill aspect for all primitives |
| 380 | for (Graphic3d_SequenceOfGroup::Iterator aGroupIt (thePrs->Groups()); aGroupIt.More(); aGroupIt.Next()) |
| 381 | { |
| 382 | const Handle(Graphic3d_Group)& aGroup = aGroupIt.Value(); |
| 383 | if (!aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_FILL_AREA)) |
| 384 | { |
| 385 | continue; |
| 386 | } |
| 387 | |
| 388 | if (aGroup->IsClosed()) |
| 389 | { |
| 390 | myAspect->SuppressBackFace(); |
| 391 | } |
| 392 | else |
| 393 | { |
| 394 | myAspect->AllowBackFace(); |
| 395 | } |
| 396 | |
| 397 | aGroup->SetGroupPrimitivesAspect (myAspect); |
| 398 | } |
| 399 | } |
| 400 | |
| 401 | //======================================================================= |
| 402 | //function : Compute |
| 403 | //purpose : |
| 404 | //======================================================================= |
| 405 | |
| 406 | void AIS_TexturedShape::Compute (const Handle(PrsMgr_PresentationManager3d)& /*thePrsMgr*/, |
| 407 | const Handle(Prs3d_Presentation)& thePrs, |
| 408 | const Standard_Integer theMode) |
| 409 | { |
| 410 | thePrs->Clear(); |
| 411 | |
| 412 | if (myshape.IsNull()) |
| 413 | { |
| 414 | return; |
| 415 | } |
| 416 | |
| 417 | if (myshape.ShapeType() > TopAbs_FACE && myshape.ShapeType() < TopAbs_SHAPE) |
| 418 | { |
| 419 | thePrs->SetVisual (Graphic3d_TOS_ALL); |
| 420 | thePrs->SetDisplayPriority (myshape.ShapeType() + 2); |
| 421 | } |
| 422 | |
| 423 | if (myshape.ShapeType() == TopAbs_COMPOUND) |
| 424 | { |
| 425 | TopExp_Explorer anExplor (myshape, TopAbs_VERTEX); |
| 426 | if (!anExplor.More()) |
| 427 | { |
| 428 | return; |
| 429 | } |
| 430 | } |
| 431 | |
| 432 | if (IsInfinite()) |
| 433 | { |
| 434 | thePrs->SetInfiniteState (Standard_True); |
| 435 | } |
| 436 | |
| 437 | switch (theMode) |
| 438 | { |
| 439 | case AIS_WireFrame: |
| 440 | { |
| 441 | StdPrs_ToolTriangulatedShape::ClearOnOwnDeflectionChange (myshape, myDrawer, Standard_True); |
| 442 | StdPrs_WFShape::Add (thePrs, myshape, myDrawer); |
| 443 | break; |
| 444 | } |
| 445 | case AIS_Shaded: |
| 446 | case 3: // texture mapping on triangulation |
| 447 | { |
| 448 | StdPrs_ToolTriangulatedShape::ClearOnOwnDeflectionChange (myshape, myDrawer, Standard_True); |
| 449 | if (myshape.ShapeType() > TopAbs_FACE) |
| 450 | { |
| 451 | StdPrs_WFShape::Add (thePrs, myshape, myDrawer); |
| 452 | break; |
| 453 | } |
| 454 | |
| 455 | myDrawer->SetShadingAspectGlobal (Standard_False); |
| 456 | if (IsInfinite()) |
| 457 | { |
| 458 | StdPrs_WFShape::Add (thePrs, myshape, myDrawer); |
| 459 | break; |
| 460 | } |
| 461 | try |
| 462 | { |
| 463 | OCC_CATCH_SIGNALS |
| 464 | if (theMode == AIS_Shaded) |
| 465 | { |
| 466 | StdPrs_ShadedShape::Add (thePrs, myshape, myDrawer); |
| 467 | } |
| 468 | else |
| 469 | { |
| 470 | StdPrs_ShadedShape::Add (thePrs, myshape, myDrawer, |
| 471 | Standard_True, |
| 472 | myIsCustomOrigin ? myUVOrigin : gp_Pnt2d (0.0, 0.0), |
| 473 | myUVRepeat, |
| 474 | myToScale ? myUVScale : gp_Pnt2d (1.0, 1.0)); |
| 475 | updateAttributes (thePrs); |
| 476 | } |
| 477 | } |
| 478 | catch (Standard_Failure) |
| 479 | { |
| 480 | #ifdef OCCT_DEBUG |
| 481 | std::cout << "AIS_TexturedShape::Compute() in ShadingMode failed \n"; |
| 482 | #endif |
| 483 | StdPrs_WFShape::Add (thePrs, myshape, myDrawer); |
| 484 | } |
| 485 | break; |
| 486 | } |
| 487 | case 2: // Bounding box |
| 488 | { |
| 489 | if (IsInfinite()) |
| 490 | { |
| 491 | StdPrs_WFShape::Add (thePrs, myshape, myDrawer); |
| 492 | } |
| 493 | else |
| 494 | { |
| 495 | StdPrs_BndBox::Add (thePrs, BoundingBox(), myDrawer); |
| 496 | } |
| 497 | break; |
| 498 | } |
| 499 | } |
| 500 | } |