Module Curve

Source Code for Module Curve

  1  # Blender.Curve module and the Curve PyType object 
  2   
  3  """ 
  4  The Blender.Curve submodule. 
  5   
  6  Curve Data 
  7  ========== 
  8   
  9  This module provides access to B{Curve Data} objects in Blender. 
 10   
 11  A Blender Curve Data consists of multiple L{CurNurb}(s). Try converting a Text object to a Curve to see an example of this.   Each curve is of 
 12  type Bezier or Nurb.  The underlying L{CurNurb}(s) can be accessed with 
 13  the [] operator.  Operator [] returns an object of type L{CurNurb}. Removing a L{CurNurb} can be done this way too. del curve[0] removes the first curve. 
 14   
 15  Note that L{CurNurb} can be used to acces a curve of any type (Poly, Bezier or Nurb) 
 16   
 17  The Curve module also supports the Python iterator interface.  This means you 
 18  can access the L{CurNurb}(s) in a Curve and the control points in a L{CurNurb} using a 
 19  Python B{for} statement. 
 20   
 21   
 22  Add a Curve to a Scene Example:: 
 23          from Blender import Curve, Object, Scene 
 24          cu = Curve.New()             # create new  curve data 
 25          scn = Scene.GetCurrent()    # get current scene 
 26          ob = scn.objects.new(cu)     # make a new curve from the curve data 
 27   
 28  Iterator Example:: 
 29          from Blender import Curve, Object, Scene 
 30          scn = Scene.GetCurrent()    # get current scene 
 31          ob = scn.objects.active 
 32          curvedata = ob.data 
 33          for curnurb in curvedata: 
 34                  print type( curnurb ), curnurb 
 35                  for point in curnurb: 
 36                          print type( point ), point 
 37   
 38  Creating a Curve from a list of Vec triples Examples:: 
 39          from Blender import * 
 40          def bezList2Curve(bezier_vecs): 
 41                  ''' 
 42                  Take a list or vector triples and converts them into a bezier curve object 
 43                  ''' 
 44                   
 45                  def bezFromVecs(vecs): 
 46                          ''' 
 47                          Bezier triple from 3 vecs, shortcut functon 
 48                          ''' 
 49                          bt= BezTriple.New(\ 
 50                          vecs[0].x, vecs[0].y, vecs[0].z,\ 
 51                          vecs[1].x, vecs[1].y, vecs[1].z,\ 
 52                          vecs[2].x, vecs[2].y, vecs[2].z) 
 53                           
 54                          bt.handleTypes= (BezTriple.HandleTypes.FREE, BezTriple.HandleTypes.FREE) 
 55                           
 56                          return bt 
 57                   
 58                  # Create the curve data with one point 
 59                  cu= Curve.New() 
 60                  cu.appendNurb(bezFromVecs(bezier_vecs[0])) # We must add with a point to start with 
 61                  cu_nurb= cu[0] # Get the first curve just added in the CurveData 
 62                   
 63                   
 64                  i= 1 # skip first vec triple because it was used to init the curve 
 65                  while i<len(bezier_vecs): 
 66                          bt_vec_triple= bezier_vecs[i] 
 67                          bt= bezFromVecs(bt_vec_triple) 
 68                          cu_nurb.append(bt) 
 69                          i+=1 
 70                   
 71                  # Add the Curve into the scene 
 72                  scn= Scene.GetCurrent() 
 73                  ob = scn.objects.new(cu) 
 74                  return ob 
 75  """ 
 76   
77 -def New ( name):
78 """ 79 Create a new Curve Data object. 80 @type name: string 81 @param name: The Curve Data name. 82 @rtype: Blender Curve 83 @return: The created Curve Data object. 84 """
85
86 -def Get (name = None):
87 """ 88 Get the Curve Data object(s) from Blender. 89 @type name: string 90 @param name: The name of the Curve Data. 91 @rtype: Blender Curve or a list of Blender Curves 92 @return: It depends on the 'name' parameter: 93 - (name): The Curve Data object with the given name; 94 - (): A list with all Curve Data objects in the current scene. 95 """
96
97 -class Curve:
98 """ 99 The Curve Data object 100 ===================== 101 This object gives access to Curve and Surface data linked from Blender Objects. 102 103 @ivar name: The Curve Data name. 104 @type name: string 105 @ivar pathlen: The Curve Data path length, used to set the number of frames for an animation (not the physical length). 106 @type pathlen: int 107 @ivar totcol: The Curve Data maximal number of linked materials. Read-only. 108 @type totcol: int 109 @ivar flag: The Curve Data flag value; see L{getFlag()} for the semantics. 110 @ivar bevresol: The Curve Data bevel resolution. [0 - 32] 111 @type bevresol: int 112 @ivar resolu: The Curve Data U-resolution (used for curve and surface resolution) [0 - 1024]. 113 @type resolu: int 114 @ivar resolv: The Curve Data V-resolution (used for surface resolution) [0 - 1024]. 115 @type resolv: int 116 @ivar width: The Curve Data width [0 - 2]. 117 @type width: float 118 @ivar ext1: The Curve Data extent1 Called "Extrude" in the user interface (for bevels only). 119 @type ext1: float 120 @ivar ext2: The Curve Data extent2 - Called "Bevel Depth" in the user interface (for bevels only). 121 @type ext2: float 122 @ivar loc: The Curve Data location(from the center). 123 @type loc: list of 3 floats 124 @ivar rot: The Curve Data rotation(from the center). 125 @type rot: list of 3 floats 126 @ivar size: The Curve Data size(from the center). 127 @type size: list of 3 floats 128 @ivar bevob: The Curve Bevel Object 129 @type bevob: Blender L{Object<Object.Object>} or None 130 @ivar taperob: The Curve Taper Object 131 @type taperob: Blender L{Object<Object.Object>} or None 132 @ivar key: The Key object associated with this Curve, if any. 133 @type key: Blender L{Key<Key.Key>} 134 @ivar materials: The curves's materials. Each curve can reference up to 135 16 materials. Empty slots in the curve's list are represented by B{None}. 136 B{Note}: L{Object.colbits<Object.Object.colbits>} needs to be set correctly 137 for each object in order for these materials to be used instead of 138 the object's materials. 139 B{Note}: The list that's returned is I{not} linked to the original curve. 140 curve.materials.append(material) won't do anything. 141 Use curve.materials += [material] instead. 142 @type materials: list of L{Material}s 143 """ 144
145 - def getName():
146 """ 147 Get the name of this Curve Data object. 148 @rtype: string 149 """
150
151 - def setName(name):
152 """ 153 Set the name of this Curve Data object. 154 @rtype: None 155 @type name: string 156 @param name: The new name. 157 """
158
159 - def getPathLen():
160 """ 161 Get this Curve's path frame length, used for an animated path. 162 @rtype: int 163 @return: the path length. 164 """
165
166 - def setPathLen(len):
167 """ 168 Set this Curve's path length. 169 @rtype: None 170 @type len: int 171 @param len: the new curve's length. 172 """
173
174 - def getTotcol():
175 """ 176 Get the number of materials linked to the Curve. 177 @rtype: int 178 @return: number of materials linked. 179 """
180
181 - def setTotcol(totcol):
182 """ 183 Set the number of materials linked to the Curve. B{Note}: this method 184 will probably be deprecated in the future. 185 @rtype: None 186 @type totcol: int 187 @param totcol: number of materials linked. 188 @warn: It is not advisable to use this method unless you know what you 189 are doing; it's possible to 190 corrupt a .blend file if you don't know what you're doing. If you want 191 to change the number of materials, use the L{materials} attribute. 192 """
193
194 - def getFlag():
195 """ 196 Get the Curve flag value. 197 This item is a bitfield whose value is a combination of the following parameters. 198 - Bit 0 : "3D" is set 199 - Bit 1 : "Front" is set 200 - Bit 2 : "Back" is set 201 - Bit 3 : "CurvePath" is set. 202 - Bit 4 : "CurveFollow" is set. 203 204 @rtype: integer bitfield 205 """
206
207 - def setFlag(val):
208 """ 209 Set the Curve flag value. The flag corresponds to the Blender settings for 3D, Front, Back, CurvePath and CurveFollow. This parameter is a bitfield. 210 @rtype: None 211 @type val: integer bitfield 212 @param val : The Curve's flag bits. See L{getFlag} for the meaning of the individual bits. 213 """
214
215 - def getBevresol():
216 """ 217 Get the Curve's bevel resolution value. 218 @rtype: float 219 """
220
221 - def setBevresol(bevelresol):
222 """ 223 Set the Curve's bevel resolution value. 224 @rtype: None 225 @type bevelresol: float 226 @param bevelresol: The new Curve's bevel resolution value. 227 """
228
229 - def getResolu():
230 """ 231 Get the Curve's U-resolution value. 232 @rtype: float 233 """
234
235 - def setResolu(resolu):
236 """ 237 Set the Curve's U-resolution value. [0 - 1024] 238 This is used for surfaces and curves. 239 @rtype: None 240 @type resolu: float 241 @param resolu: The new Curve's U-resolution value. 242 """
243
244 - def getResolv():
245 """ 246 Get the Curve's V-resolution value. 247 @rtype: float 248 """
249
250 - def setResolv(resolv):
251 """ 252 Set the Curve's V-resolution value. [0 - 1024]. 253 This is used for surfaces only. 254 @rtype: None 255 @type resolv: float 256 @param resolv: The new Curve's V-resolution value. 257 """
258
259 - def getWidth():
260 """ 261 Get the Curve's width value. 262 @rtype: float 263 """
264
265 - def setWidth(width):
266 """ 267 Set the Curve's width value. 268 @rtype: None 269 @type width: float 270 @param width: The new Curve's width value. 271 """
272
273 - def getExt1():
274 """ 275 Get the Curve's ext1 value. 276 @rtype: float 277 """
278
279 - def setExt1(ext1):
280 """ 281 Set the Curve's ext1 value. 282 @rtype: None 283 @type ext1: float 284 @param ext1: The new Curve's ext1 value. 285 """
286
287 - def getExt2():
288 """ 289 Get the Curve's ext2 value. 290 @rtype: float 291 """
292
293 - def setExt2(ext2):
294 """ 295 Set the Curve's ext2 value. 296 @rtype: None 297 @type ext2: float 298 @param ext2: The new Curve's ext2 value. 299 """
300
301 - def getControlPoint(numcurve,numpoint):
302 """ 303 Get the curve's control point value (B{deprecated}). The numpoint arg 304 is an index into the list of points and starts with 0. B{Note}: new 305 scripts should use the [] operator on Curves and CurNurbs. Example:: 306 curve = Blender.Curve.Get('Curve') 307 p0 = curve[0][0] # get first point from first nurb 308 # -- OR -- 309 nurb = curve[0] # get first nurb 310 p0 = nurb[0] # get nurb's first point 311 312 @type numcurve: int 313 @type numpoint: int 314 @rtype: list of floats 315 @return: depends upon the curve's type. 316 - type Bezier : a list of nine floats. Values are x, y, z for handle-1, vertex and handle-2 317 - type Nurb : a list of 4 floats. Values are x, y, z, w. 318 319 """
320
321 - def setControlPoint( numcurve, numpoint, controlpoint):
322 """ 323 Set the Curve's controlpoint value. The numpoint arg is an index into the list of points and starts with 0. 324 @rtype: None 325 @type numcurve: int 326 @type numpoint: int 327 @type controlpoint: list 328 @param numcurve: index for spline in Curve, starting from 0 329 @param numpoint: index for point in spline, starting from 0 330 @param controlpoint: The new controlpoint value. 331 See L{getControlPoint} for the length of the list. 332 """
333
334 - def appendPoint( numcurve, new_control_point ):
335 """ 336 Add a new control point to the indicated curve (B{deprecated}). 337 New scripts should use L{CurNurb.append()}. 338 @rtype: None 339 @type numcurve: int 340 @type new_control_point: list of floats or BezTriple 341 @param numcurve: index for spline in Curve, starting from 0 342 @param new_control_point: depends on curve's type. 343 - type Bezier: a BezTriple 344 - type Nurb: a list of four or five floats for the xyzw values 345 @raise AttributeError: throws exception if numcurve is out of range. 346 """
347
348 - def appendNurb( new_point ):
349 """ 350 add a new curve to this Curve. The new point is added to the new curve. Blender does not support a curve with zero points. The new curve is added to the end of the list of curves in the Curve. 351 @rtype: CurNurb 352 @return: the newly added spline 353 @type new_point: BezTriple or list of xyzw coordinates for a Nurb curve. 354 @param new_point: see L{CurNurb.append} for description of parameter. 355 """
356
357 - def getLoc():
358 """ 359 Get the curve's location value. 360 @rtype: a list of 3 floats. 361 """
362
363 - def setLoc(location):
364 """ 365 Set the curve's location value. 366 @rtype: None 367 @type location: list[3] 368 @param location: The new Curve's location values. 369 """
370
371 - def getRot():
372 """ 373 Get the curve's rotation value. 374 @rtype: a list of 3 floats. 375 """
376
377 - def setRot(rotation):
378 """ 379 Set the Curve's rotation value. 380 @rtype: None 381 @type rotation: list[3] 382 @param rotation: The new Curve's rotation values. 383 """
384
385 - def getSize():
386 """ 387 Get the curve's size value. 388 @rtype: a list of 3 floats. 389 """
390
391 - def setSize(size):
392 """ 393 Set the curve size value. 394 @rtype: None 395 @type size: list[3] 396 @param size: The new Curve's size values. 397 """
398
399 - def getMaterials():
400 """ 401 Returns a list of materials assigned to the Curve. 402 @rtype: list of Material Objects 403 @return: list of Material Objects assigned to the Curve. 404 """
405
406 - def getBevOb():
407 """ 408 Returns the Bevel Object (BevOb) assigned to the Curve. 409 @rtype: Blender Object or None 410 @return: Bevel Object (BevOb) assigned to the Curve. 411 """
412
413 - def setBevOb( object ):
414 """ 415 Assign a Bevel Object (BevOb) to the Curve. Passing None as the object parameter removes the bevel. 416 @rtype: None 417 @return: None 418 @type object: Curve type Blender Object 419 @param object: Blender Object to assign as Bevel Object (BevOb) 420 @raise TypeError: throws exception if the parameter is not a Curve type Blender Object or None 421 """
422
423 - def getTaperOb():
424 """ 425 Returns the Taper Object (TaperOb) assigned to the Curve. 426 @rtype: Blender Object or None 427 @return: Taper Object (TaperOb) assigned to the Curve. 428 """
429
430 - def setTaperOb( object ):
431 """ 432 Assign a Taper Object (TaperOb) to the Curve. Passing None as the object parameter removes the taper. 433 @rtype: None 434 @return: None 435 @type object: Curve type Blender Object 436 @param object: Blender Object to assign as Taper Object (TaperOb) 437 @raise TypeError: throws exception if the parameter is not a Curve type Blender Object or None 438 """
439
440 - def update():
441 """ 442 Updates display list for a Curve. 443 Used after making changes to control points. 444 You B{must} use this if you want to see your changes! 445 @rtype: None 446 @return: None 447 """
448
449 - def isNurb( curve_num ):
450 """ 451 Tells type of a CurNurb (B{deprecated}). 452 New scripts should use L{CurNurb.isNurb()}. 453 454 @rtype: integer 455 @return: Zero if curve is type Bezier, one if curve is of type Nurb. 456 @type curve_num: integer 457 @param curve_num: zero-based index into list of curves in this Curve. 458 @raise AttributeError: throws exception if curve_num is out of range. 459 """
460
461 - def isCyclic( curve_num ):
462 """ 463 Tells whether or not a CurNurb is cyclic (closed) (B{deprecated}). 464 New scripts should use L{CurNurb.isCyclic()}. 465 466 @rtype: boolean 467 @return: True if is cyclic, False if not 468 @type curve_num: integer 469 @param curve_num: zero-based index into list of curves in this Curve 470 @raise AttributeError: throws exception if curve_num is out of range. 471 """
472
473 - def switchDirection( ):
474 """ 475 Reverse the direction of a curve. 476 @return: None 477 478 I{B{Example:}} 479 # This example switches the direction of all curves on the active object. 480 from Blender import * 481 scn = Scene.GetCurrent() 482 ob = scn.objects.active # must be a curve 483 data = ob.data 484 for cu in data: cu.switchDirection() 485 """
486
487 - def getNumCurves():
488 """ 489 Get the number of curves in this Curve Data object. 490 @rtype: integer 491 """
492
493 - def getNumPoints( curve_num ):
494 """ 495 Get the number of control points in the curve (B{deprecated}). 496 New scripts should use the len operator (I{len(curve)}). 497 @type curve_num: integer 498 @param curve_num: zero-based index into list of curves in this Curve 499 @rtype: integer 500 """
501
502 - def getKey():
503 """ 504 Return the L{Key<Key.Key>} object containing the keyframes for this 505 curve, if any. 506 @rtype: L{Key<Key.Key>} object or None 507 """
508
509 - def recalc():
510 """ 511 Recalculate control point handles after a curve has been changed. 512 @rtype: None 513 """
514
515 - def __copy__ ():
516 """ 517 Make a copy of this curve 518 @rtype: Curve 519 @return: a copy of this curve 520 """
521
522 -class CurNurb:
523 """ 524 The CurNurb Object 525 ================== 526 This object provides access to the control points of the curves that make up a Blender Curve ObData. 527 528 The CurNurb supports the python iterator protocol which means you can use a python for statement to access the points in a curve. 529 530 The CurNurb also supports the sequence protocol which means you can access the control points of a CurNurb using the [] operator. 531 532 Note that CurNurb is used for accesing poly, bezier and nurbs type curves. 533 534 @ivar flagU: The CurNurb knot flag U. See L{setFlagU} for description. 535 @type flagU: int 536 @ivar flagV: The CurNurb knot flag V. See L{setFlagU} for description. 537 @type flagV: int 538 @ivar type: The type of the curve (Poly: 0, Bezier: 1, NURBS: 4) 539 @type type: int 540 @ivar knotsU: The knot vector in the U direction. The tuple will be empty 541 if the curve isn't a NURB or doesn't have knots in this direction. 542 @type knotsU: tuple of floats 543 @ivar knotsV: The knot vector in the V direction. The tuple will be empty 544 if the curve isn't a NURB or doesn't have knots in this direction. 545 @type knotsV: tuple of floats 546 @ivar smooth: Set the smoothing for this curve (applies to cuve objects that have a bevel) 547 @type smooth: bool 548 """ 549
550 - def __setitem__( n, point ):
551 """ 552 Replace the Nth point in the curve. The type of the argument must match the type of the curve. List of 4 floats (optional 5th float is the tilt value in radians) for Nurbs or BezTriple for Bezier. 553 @rtype: None 554 @return: None 555 @type n: integer 556 @param n: the index of the element to replace 557 @type point: BezTriple or list of 4 floats (optional 5th float is the tilt value in radians) 558 @param point: the point that will replace the one in the curve. The point can be either a BezTriple type or a list of 4 floats in x,y,z,w (optionally tilt in radians as 5th value) format for a Nurb curve. 559 """
560
561 - def __getitem__( n ):
562 """ 563 Get the Nth element in the curve. For Bezier curves, that element is a BezTriple. For the rest (Poly and Nurbs), it is a list of 5 floats: x, y, z, weight, tilt (in radians). NOTE 1: This element is independent on the curve, modifying it will not affect the curve. NOTE 2: Each successive call returns a new object. 564 @rtype: BezTriple (Bezier Curve) or List of 5 floats [x, y, z, w, t] for Poly or Nurbs 565 @return: The Nth element in the curve 566 @type n: integer 567 @param n: the index of the element to return 568 """
569
570 - def append( new_point ):
571 """ 572 Appends a new point to a curve. This method appends points to both Bezier and Nurb curves. The type of the argument must match the type of the curve. List of 4 floats (optional 5th float is the tilt value in radians) for Nurbs or BezTriple for Bezier. 573 @rtype: None 574 @return: None 575 @type new_point: BezTriple or list of 4 floats (optional 5th float is the tilt value in radians) 576 @param new_point: the new point to be appended to the curve. The new point can be either a BezTriple type or a list of 4 floats in x,y,z,w (optionally tilt in radians as 5th value) format for a Nurb curve. 577 """
578
579 - def setMatIndex( index ):
580 """ 581 Sets the Material index for this CurNurb. 582 @rtype: None 583 @return: None 584 @type index: integer 585 @param index: the new value for the Material number of this CurNurb. No range checking is done. 586 """
587
588 - def getMatIndex():
589 """ 590 Returns the Material index for this CurNurb. 591 @rtype: integer 592 @return: integer 593 """
594
595 - def isNurb():
596 """ 597 Boolean method used to determine whether a CurNurb is of type Bezier or of type Nurb. 598 @rtype: boolean 599 @return: True or False 600 """
601
602 - def isCyclic():
603 """ 604 Boolean method checks whether a CurNurb is cyclic (a closed curve) or not. 605 @rtype: boolean 606 @return: True or False 607 """
608
609 - def getFlagU():
610 """ 611 Get the CurNurb knot flag U. 612 @rtype: integer 613 @return: See L{setFlagU} for description of return value. 614 """
615
616 - def setFlagU( flag ):
617 """ 618 Set the entire CurNurb knot flag U (knots are recalculated automatically). 619 The flag can be one of six values: 620 - 0 or 1: uniform knots 621 - 2 or 3: endpoints knots 622 - 4 or 5: bezier knots 623 Bit 0 controls whether or not the curve is cyclic (1 = cyclic). 624 @type flag: integer 625 @param flag: CurNurb knot flag 626 @rtype: None 627 @return: None 628 """
629
630 - def getFlagV():
631 """ 632 Get the CurNurb knot flag V. 633 @rtype: integer 634 @return: See L{setFlagU} for description of return value. 635 """
636
637 - def setFlagV( value ):
638 """ 639 Set the CurNurb knot flag V (knots are recalculated automatically). 640 @type value: integer 641 @param value: See L{setFlagU} for description of return. 642 @rtype: None 643 @return: None 644 """
645
646 - def getType():
647 """ 648 Get the type of the curve. 649 @rtype: integer 650 @return: 0 - Poly, 1 - Bezier, 4 - NURBS 651 """
652
653 - def setType( value ):
654 """ 655 Set the type of the curve and converts the curve to its new type if needed 656 @type value: integer 657 @param value: CurNurb type flag (0 - Poly, 1 - Bezier, 4 - NURBS) 658 @rtype: None 659 @return: None 660 """
661
662 -class SurfNurb:
663 """ 664 The SurfNurb Object 665 =================== 666 This object provides access to the control points of the surfaces that make 667 up a Blender Curve. 668 669 The SurfNurb supports the Python iterator and sequence protocols which 670 means you can use a python B{for} statement or [] operator to access the 671 points in a surface. Points are accessed linearly; for a N-by-M UV surface, 672 the first N control points correspond to V=0, then second N to V=1, and so 673 on. 674 675 @ivar flagU: The knot flag U. Changing the knot type automatically 676 recalculates the knots. The flag can be one of three values: 677 - 0 : uniform knots 678 - 1 : endpoints knots 679 - 2 : bezier knots 680 @type flagU: int 681 @ivar flagV: The knot flag V. See L{flagU} for description. 682 @type flagV: int 683 @ivar pointsU: The number of control points in the U direction (read only). 684 @type pointsU: int 685 @ivar pointsV: The number of control points in the V direction (read only). 686 @type pointsV: int 687 @ivar cyclicU: The cyclic setting for the U direction (True = cyclic). 688 @type cyclicU: boolean 689 @ivar cyclicV: The cyclic setting for the V direction (True = cyclic). 690 @type cyclicV: boolean 691 @ivar orderU: The order setting for the U direction. Values are clamped 692 to the range [2:6] and not greater than the U dimension. 693 @type orderU: int 694 @ivar orderV: The order setting for the V direction. Values are clamped 695 to the range [2:6] and not greater than the V dimension. 696 @type orderV: int 697 @ivar knotsU: The The knot vector in the U direction 698 @type knotsU: tuple 699 @ivar knotsV: The The knot vector in the V direction 700 @type knotsV: tuple 701 """ 702
703 - def __setitem__( n, point ):
704 """ 705 Set the Nth control point in the surface. 706 @rtype: None 707 @return: None 708 @type n: integer 709 @param n: the index of the point to replace 710 @type point: list of 4 floats (optional 5th float is the tilt value 711 in radians) 712 @param point: the point that will replace the one in the curve. The 713 point is list of 4 floats in x,y,z,w (optionally tilt in radians as 714 5th value) format. 715 """
716
717 - def __getitem__( n ):
718 """ 719 Get the Nth control point in the surface. 720 @rtype: List of 5 floats [x, y, z, w, t] for Poly or Nurbs 721 @return: The Nth point in the curve 722 @type n: integer 723 @param n: the index of the point to return 724 @note: This returned value is independent on the curve; modifying it will not affect the curve. 725 @note: Each successive call returns a new object. 726 """
727