HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SOP_BrushHairLen.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2022
3  * Side Effects Software Inc. All rights reserved.
4  *
5  * Redistribution and use of Houdini Development Kit samples in source and
6  * binary forms, with or without modification, are permitted provided that the
7  * following conditions are met:
8  * 1. Redistributions of source code must retain the above copyright notice,
9  * this list of conditions and the following disclaimer.
10  * 2. The name of Side Effects Software may not be used to endorse or
11  * promote products derived from this software without specific prior
12  * written permission.
13  *
14  * THIS SOFTWARE IS PROVIDED BY SIDE EFFECTS SOFTWARE `AS IS' AND ANY EXPRESS
15  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
17  * NO EVENT SHALL SIDE EFFECTS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
18  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
19  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
20  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
21  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
22  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
23  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  *
25  *----------------------------------------------------------------------------
26  */
27 
28 #ifndef __SOP_BrushHairLen__
29 #define __SOP_BrushHairLen__
30 
31 #include <SOP/SOP_Node.h>
32 #include <SOP/SOP_BrushBase.h>
33 
34 namespace HDK_Sample {
36 {
37 public:
38  SOP_BrushHairLen(OP_Network *net, const char *, OP_Operator *entry);
39  ~SOP_BrushHairLen() override;
40 
41  static OP_Node *myConstructor(OP_Network *net, const char *name,
42  OP_Operator *entry);
44 
45  /// This is the callback triggered when a BRUSHOP_CALLBACK is used:
46  void brushOpCallback(
47  fpreal t,
48  GA_Offset pt,
49  const UT_Array<GA_Offset> *ptneighbour,
50  GA_Offset vtx,
51  const UT_Array<GA_Offset> *vtxneighbour,
52  float alpha,
53  GEO_Delta *delta,
54  const GU_Detail *gdp) override;
55 
56 protected:
57  OP_ERROR cookMySop(OP_Context &context) override;
58 
59  /// These are the many & various methods used by BrushBase to
60  /// determine the current brush status. We can either hook them
61  /// up to parameters (via evalFloat) or hard code them. In this
62  /// case we have hard coded most.
63 
64  /// Public methods needed by MSS:
65 public:
66  /// Finds the geometry to do the intersection with.
67  const GU_Detail *getIsectGdp(fpreal t) override;
68 
69  /// If the action of the brush will change point positions,
70  /// we should set this to 1. We create geometry, but leave point
71  /// positions untouched.
72  int altersGeometry() const override
73  { return 0; }
74  /// We do attribute changes.
75  int altersColor() const override
76  { return 1; }
77  /// This gets the current radius of the brush, unmodulated by the
78  /// current pressure amount.
80  { return evalFloat("radius", 0, t); }
81  /// This gets the raw radius for the UV space.
83  { return evalFloat("uvradius", 0, t); }
84  /// This is how much the HITPRESSURE should affect the RADIUS.
85  fpreal RADIUSPRESSURE(fpreal /*t*/) override
86  { return 1.0f; }
87  /// The opacity, hardcoded to 1.0f, for a full replace
88  fpreal RAWOPACITY(fpreal /*t*/) override
89  { return 1.0f; }
90  fpreal OPACITYPRESSURE(fpreal /*t*/) override
91  { return 1.0f; }
92 
93  /// This is how far along the brush axis it will be able to paint.
94  /// We tie it directly to the raidus here.
95  fpreal DEPTH(fpreal t) override
96  { return evalFloat("radius", 0, t); }
97  fpreal HEIGHT(fpreal t) override
98  { return evalFloat("radius", 0, t); }
99  /// Whether to use depth clipping at all.
100  int USEDEPTH() override
101  { return 1; }
102  /// Whether to not paint across unconnected seams. We are using depth
103  /// clipping in this tool, so have it off.
104  int USECONNECTIVITY() override
105  { return 0; }
106 
107  /// This needs to map our OP_Menu into SOP_BrushOp. We leave this
108  /// to the C code.
109  SOP_BrushOp OP() override;
110 
111  /// Whether accumulate stencil is currently on. We keep it off.
112  int ACCUMSTENCIL() override
113  { return 0; }
114  /// Projection Type 1 is orient to surface, 0 is to use it flat on.
115  /// We hard code it to flat on.
116  int PROJECTIONTYPE() override
117  { return 0; }
118  /// In realtime mode, all changes are applied immediately to the
119  /// gdp, rather than being stored in the CurrentDelta during a brush
120  /// stroke. Some types of brushing require this behaviour implicitly.
121  int REALTIME() override
122  { return 1; }
123  /// This returns a SOP_BrushShape. We hardcode to circle.
124  int SHAPE(fpreal /*t*/) override
125  { return SOP_BRUSHSHAPE_CIRCLE; }
126 
127  /// Protected methods needed by SOP_BrushBase:
128 protected:
129  /// This returns a GU_BrushMergeMode, defined in GU_Brush.h
130  /// We just use the standard replace.
131  int MERGEMODE() override
132  { return GU_BRUSHMERGEMODE_REPLACE; }
133 
134  /// Not used:
135  void SCRIPT(UT_String & /*s*/, fpreal /*t*/) override
136  { }
137 
138  /// These are used by deformation brush ops:
139  int AXIS() override
140  { return 0; }
141  fpreal USERX(fpreal /*t*/) override
142  { return 0.0f; }
143  fpreal USERY(fpreal /*t*/) override
144  { return 0.0f; }
145  fpreal USERZ(fpreal /*t*/) override
146  { return 0.0f; }
147 
148  /// These query the current raystate. We read off the cached values...
149  fpreal RAYORIENTX(fpreal /*t*/) override
150  { return myRayOrient.x(); }
151  fpreal RAYORIENTY(fpreal /*t*/) override
152  { return myRayOrient.y(); }
153  fpreal RAYORIENTZ(fpreal /*t*/) override
154  { return myRayOrient.z(); }
155  fpreal RAYHITX(fpreal /*t*/) override
156  { return myRayHit.x(); }
157  fpreal RAYHITY(fpreal /*t*/) override
158  { return myRayHit.y(); }
159  fpreal RAYHITZ(fpreal /*t*/) override
160  { return myRayHit.z(); }
161  fpreal RAYHITU(fpreal /*t*/) override
162  { return myRayHitU; }
163  fpreal RAYHITV(fpreal /*t*/) override
164  { return myRayHitV; }
165  fpreal RAYHITW(fpreal /*t*/) override
166  { return myRayHitW; }
167  fpreal RAYHITPRESSURE(fpreal /*t*/) override
168  { return myRayHitPressure; }
169  int PRIMHIT(fpreal /*t*/) override
170  { return myPrimHit; }
171  int PTHIT(fpreal /*t*/) override
172  { return myPtHit; }
173  int EVENT() override
174  { return myEvent; }
175 
176  /// These query the current "colours" of the brush...
177  /// F is for foreground, B, for background. Up to a 3 vector is
178  /// possible in the order R, G, B.
179  /// If USE_FOREGROUND is true, the F will be used, otherwise B.
180  bool USE_FOREGROUND() override
181  { return myUseFore; }
182  fpreal FGR(fpreal t) override
183  { return evalFloat("flen", 0, t); }
184  fpreal FGG(fpreal /*t*/) override
185  { return 0.0f; }
186  fpreal FGB(fpreal /*t*/) override
187  { return 0.0f; }
188  fpreal BGR(fpreal t) override
189  { return evalFloat("blen", 0, t); }
190  fpreal BGG(fpreal /*t*/) override
191  { return 0.0f; }
192  fpreal BGB(fpreal /*t*/) override
193  { return 0.0f; }
194 
195  /// These control the shape of the nib. We have hard coded
196  /// most of them...
197  /// What percentage of the radius to devote to the fall off curve.
198  fpreal SOFTEDGE(fpreal /*t*/) override
199  { return 1.0f; }
200  /// Which metaball kernel to use as the fall off curve.
201  void KERNEL(UT_String &str, fpreal /*t*/) override
202  { str = "Elendt"; }
203  /// How to determine the upvector, unnecessary with circular brushes.
204  int UPTYPE(fpreal /*t*/) override
205  { return 0; }
206  fpreal UPX(fpreal /*t*/) override
207  { return 0.0f; }
208  fpreal UPY(fpreal /*t*/) override
209  { return 0.0f; }
210  fpreal UPZ(fpreal /*t*/) override
211  { return 0.0f; }
212 
213  /// Alpha noise in the paper space
214  fpreal PAPERNOISE(fpreal /*t*/) override
215  { return 0.0f; }
216  /// Alpha noise in the brush space
217  fpreal SPLATTER(fpreal /*t*/) override
218  { return 0.0f; }
219  /// Name of the bitmap to use if bitmap brush is on, which it isn't.
220  void BITMAP(UT_String & /*str*/, fpreal /*t*/) override
221  { }
222  /// Which channel of the bitmap brush should be used.
223  int BITMAPCHAN(fpreal /*t*/) override
224  { return 0; }
225  /// More hard coded stuff directly from the Nib tab...
226  fpreal ANGLE(fpreal /*t*/) override
227  { return 0.0f; }
228  fpreal SQUASH(fpreal /*t*/) override
229  { return 1.0f; }
230  int DOSTAMPING() override
231  { return 0; }
232  int WRITEALPHA() override
233  { return 0; }
234  /// We explicitly override these parameters as we want the brush
235  /// to automatically edit our "hairlen" point attribute.
236  int OVERRIDECD() override
237  { return 1; }
238  void CDNAME(UT_String &str, fpreal /*t*/) override
239  { str = "hairlen"; }
240  /// As WRITEALPHA is off, this is irrelevant:
241  int OVERRIDEALPHA() override
242  { return 0; }
243  void ALPHANAME(UT_String & /*str*/, fpreal /*t*/) override
244  { }
245  /// For Comb style brushes, this preserves the normal length.
246  int PRESERVENML() override
247  { return 0; }
248  /// For Comb style brushes this allows overriding the normal attribute.
249  int OVERRIDENML() override
250  { return 0; }
251  void NMLNAME(UT_String & /*str*/, fpreal /*t*/) override
252  { }
253 
254  /// These methods are used to get the current symmetry operations
255  /// that are enabled with the brush. We don't use any of them here.
256  int DOREFLECTION() override
257  { return 0; }
258  int DOROTATION() override
259  { return 0; }
260  fpreal SYMMETRYDIRX(fpreal /*t*/) override
261  { return 0.0f; }
262  fpreal SYMMETRYDIRY(fpreal /*t*/) override
263  { return 0.0f; }
264  fpreal SYMMETRYDIRZ(fpreal /*t*/) override
265  { return 0.0f; }
266  fpreal SYMMETRYORIGX(fpreal /*t*/) override
267  { return 0.0f; }
268  fpreal SYMMETRYORIGY(fpreal /*t*/) override
269  { return 0.0f; }
270  fpreal SYMMETRYORIGZ(fpreal /*t*/) override
271  { return 0.0f; }
272  int SYMMETRYROT(fpreal /*t*/) override
273  { return 0; }
274  fpreal SYMMETRYDIST(fpreal /*t*/) override
275  { return 0.0f; }
276 
277  /// This determines if the Cd or Normal should be auto-added.
278  /// We have it off as we add it by hand in our cook.
279  int ADDATTRIB() override
280  { return 0; }
281  /// This determines if visualization will occur.
282  int VISUALIZE() override
283  { return 0; }
284  int VISTYPE() override
285  { return 0; }
286  fpreal VISLOW(fpreal /*t*/) override
287  { return 0.0f; }
288  fpreal VISHIGH(fpreal /*t*/) override
289  { return 1.0f; }
290  int VISMODE() override
291  { return 0; }
293  { return 1.0f; }
295  { return 1.0f; }
297  { return 1.0f; }
298 
299  /// This is used by capture brushes to determine if they should
300  /// normalize the weights.
301  int NORMALIZEWEIGHT() override
302  { return 0; }
303 
304  /// Should return true if this brush will affect capture regions.
305  int USECAPTURE() override
306  { return 0; }
307  /// Returns the capture region to brush for such brushes.
308  int CAPTUREIDX(fpreal /*t*/) override
309  { return 0; }
310 
311  /// These determine if the relevant parameters have changed. They are
312  /// often used to determine when to invalidate internal caches.
313 
314  /// hasStrokeChanged should return true if any of the setHit* were called,
315  /// as it will cause a new dab to be applied.
316  bool hasStrokeChanged(fpreal /*t*/) override
317  { return myStrokeChanged; }
318  /// This should return true if the style of the brush changed, specifically
319  /// the foreground or background colours. We test this trhough isParmDirty
320  /// in the C code.
321  bool hasStyleChanged(fpreal t) override;
322  /// This determines if the nib file changed. We don't have a nib file.
323  bool hasNibFileChanged(fpreal /*t*/) override
324  { return false; }
325  /// This returns true if any nib parameters (such as shape, etc) have
326  /// changed since the last cook.
327  bool hasNibLookChanged(fpreal /*t*/) override
328  { return false; }
329  /// This returns true if the type of accumulation mode changed.
330  bool hasAccumStencilChanged(fpreal /*t*/) override
331  { return false; }
332  /// This returns true if the capture index has changed.
333  bool hasCaptureIdxChanged(fpreal /*t*/) override
334  { return false; }
335  /// This return strue if the visualization range has changed.
336  bool hasVisrangeChanged(fpreal /*t*/) override
337  { return false; }
338 
339  /// If this returns true, the selection will be cooked as the
340  /// group. We don't want that, so return false.
341  bool wantsCookSelection() const override
342  { return false; }
343 
344  /// public methods used by MSS level to write to this level:
345  /// The usual brush ops (such as Paint, etc) will set parameters
346  /// with these values. We just cache them locally here.
347 public:
348  /// We are locking off accumulate stencil (ACCUMSTENCIL) so can
349  /// ignore attempts to turn it on.
350  void setAccumulateStencil(bool /*yesno*/) override {}
351  void setRayOrigin(const UT_Vector3 &orig, fpreal /*t*/) override
352  { myRayHit = orig; myStrokeChanged = true; forceRecook(); }
353  void setRayOrientation(const UT_Vector3 &orient, fpreal /*t*/) override
354  { myRayOrient = orient; myStrokeChanged = true; forceRecook(); }
355  void setHitPrimitive(int primidx, fpreal /*t*/) override
356  { myPrimHit = primidx; myStrokeChanged = true; forceRecook(); }
357  void setHitPoint(int ptidx, fpreal /*t*/) override
358  { myPtHit = ptidx; myStrokeChanged = true; forceRecook(); }
359  void setHitUVW(fpreal u, fpreal v, fpreal w, fpreal /*t*/) override
360  {
361  myRayHitU = u;
362  myRayHitV = v;
363  myRayHitW = w;
364  myStrokeChanged = true;
365  forceRecook();
366  }
367  void setHitPressure(fpreal pressure, fpreal /*t*/) override
368  { myRayHitPressure = pressure; myStrokeChanged = true; forceRecook(); }
370  { myEvent = event; myStrokeChanged = true; forceRecook(); }
371  /// This one must map from SOP_BrushOp into our own op menu.
372  /// Thus it is left to the C file.
373  void setBrushOp(SOP_BrushOp op) override;
374  /// As we are always returning CIRCLE for SHAPE(), we ignore
375  /// requests to change the brush shape.
376  void setBrushShape(SOP_BrushShape /*shape*/) override {}
377  /// As we are locking projection type to not orient to surface,
378  /// we can ignore these change requests (see PROJECTIONTYPE)
379  void setProjectionType(int /*projtype*/) override {}
380  void useForegroundColor() override
381  { myUseFore = true; }
382  void useBackgroundColor() override
383  { myUseFore = false; }
384  /// This is used by the eyedropper to write into the current colour
385  /// field.
386  void setCurrentColor(const UT_Vector3 &cd) override
387  {
388  setFloat(myUseFore ? "flen" : "blen", 0, 0, cd.x());
389  }
390 
391  /// This is used to update the radii from the state:
392  void setRadius(fpreal r, fpreal t) override
393  {
394  setFloat("radius", 0, t, r);
395  }
396  void setUVRadius(fpreal r, fpreal t) override
397  {
398  setFloat("uvradius", 0, t, r);
399  }
400 
401 protected:
402  /// This method handles the erase callback relevant to this type
403  /// of brush.
404  void doErase() override;
405 
406 private:
407  /// Here we cache the current ray hit values...
408  UT_Vector3 myRayOrient, myRayHit;
409  float myRayHitU, myRayHitV, myRayHitW;
410  float myRayHitPressure;
411  int myPrimHit;
412  int myPtHit;
413  int myEvent;
414  bool myUseFore;
415  bool myStrokeChanged;
416 
417 
418  /// These are cached for the brushop callback to know the attribute
419  /// indices.
420  bool myHairlenFound;
421  GA_RWHandleF myHairlenHandle;
422  fpreal myTime;
423 };
424 } // End HDK_Sample namespace
425 
426 #endif
fpreal SYMMETRYDIRZ(fpreal) override
bool wantsCookSelection() const override
fpreal SYMMETRYDIRY(fpreal) override
int PRIMHIT(fpreal) override
bool hasCaptureIdxChanged(fpreal) override
This returns true if the capture index has changed.
void setAccumulateStencil(bool) override
fpreal VISHIGH(fpreal) override
void setHitUVW(fpreal u, fpreal v, fpreal w, fpreal) override
void KERNEL(UT_String &str, fpreal) override
Which metaball kernel to use as the fall off curve.
fpreal RAYHITU(fpreal) override
bool hasNibLookChanged(fpreal) override
fpreal FGG(fpreal) override
int altersColor() const override
We do attribute changes.
fpreal ZEROWEIGHTCOLOR_B() override
void setProjectionType(int) override
fpreal SYMMETRYORIGZ(fpreal) override
fpreal BGR(fpreal t) override
SOP_BrushOp OP() override
fpreal RAWRADIUS(fpreal t) override
void brushOpCallback(fpreal t, GA_Offset pt, const UT_Array< GA_Offset > *ptneighbour, GA_Offset vtx, const UT_Array< GA_Offset > *vtxneighbour, float alpha, GEO_Delta *delta, const GU_Detail *gdp) override
This is the callback triggered when a BRUSHOP_CALLBACK is used:
OP_ERROR cookMySop(OP_Context &context) override
constexpr SYS_FORCE_INLINE T & z() noexcept
Definition: UT_Vector3.h:656
virtual void forceRecook(bool evensmartcache=true)
fpreal evalFloat(int pi, int vi, fpreal t) const
bool hasNibFileChanged(fpreal) override
This determines if the nib file changed. We don't have a nib file.
fpreal SOFTEDGE(fpreal) override
UT_ErrorSeverity
Definition: UT_Error.h:25
fpreal VISLOW(fpreal) override
fpreal HEIGHT(fpreal t) override
const GU_Detail * getIsectGdp(fpreal t) override
Public methods needed by MSS:
void setBrushShape(SOP_BrushShape) override
fpreal PAPERNOISE(fpreal) override
Alpha noise in the paper space.
bool hasAccumStencilChanged(fpreal) override
This returns true if the type of accumulation mode changed.
fpreal RAYORIENTX(fpreal) override
These query the current raystate. We read off the cached values...
GLuint const GLchar * name
Definition: glcorearb.h:786
GLdouble GLdouble t
Definition: glew.h:1403
int OVERRIDEALPHA() override
As WRITEALPHA is off, this is irrelevant:
fpreal RAYHITPRESSURE(fpreal) override
void setBrushEvent(SOP_BrushEvent event) override
fpreal ANGLE(fpreal) override
More hard coded stuff directly from the Nib tab...
void setRayOrientation(const UT_Vector3 &orient, fpreal) override
struct _cl_event * event
Definition: glcorearb.h:2961
GLubyte GLubyte GLubyte GLubyte w
Definition: glcorearb.h:857
bool hasStyleChanged(fpreal t) override
int CAPTUREIDX(fpreal) override
Returns the capture region to brush for such brushes.
GA_Size GA_Offset
Definition: GA_Types.h:640
fpreal ZEROWEIGHTCOLOR_G() override
fpreal RAWOPACITY(fpreal) override
The opacity, hardcoded to 1.0f, for a full replace.
bool hasVisrangeChanged(fpreal) override
This return strue if the visualization range has changed.
fpreal OPACITYPRESSURE(fpreal) override
void NMLNAME(UT_String &, fpreal) override
fpreal SYMMETRYDIRX(fpreal) override
int USECAPTURE() override
Should return true if this brush will affect capture regions.
int PTHIT(fpreal) override
fpreal RAWUVRADIUS(fpreal t) override
This gets the raw radius for the UV space.
void setUVRadius(fpreal r, fpreal t) override
fpreal BGB(fpreal) override
void setRadius(fpreal r, fpreal t) override
This is used to update the radii from the state:
fpreal BGG(fpreal) override
const GLdouble * v
Definition: glcorearb.h:837
void SCRIPT(UT_String &, fpreal) override
Not used:
static OP_Node * myConstructor(OP_Network *net, const char *name, OP_Operator *entry)
fpreal USERY(fpreal) override
fpreal RAYHITV(fpreal) override
int AXIS() override
These are used by deformation brush ops:
int SYMMETRYROT(fpreal) override
fpreal USERZ(fpreal) override
SOP_BrushOp
Definition: SOP_BrushBase.h:39
void setCurrentColor(const UT_Vector3 &cd) override
int OVERRIDENML() override
For Comb style brushes this allows overriding the normal attribute.
int UPTYPE(fpreal) override
How to determine the upvector, unnecessary with circular brushes.
fpreal FGB(fpreal) override
GA_API const UT_StringHolder orient
fpreal UPZ(fpreal) override
int SHAPE(fpreal) override
This returns a SOP_BrushShape. We hardcode to circle.
GU_Detail * gdp
Definition: SOP_Node.h:1615
fpreal SYMMETRYORIGY(fpreal) override
void setRayOrigin(const UT_Vector3 &orig, fpreal) override
int USEDEPTH() override
Whether to use depth clipping at all.
fpreal RAYHITY(fpreal) override
fpreal RAYORIENTY(fpreal) override
fpreal RAYHITZ(fpreal) override
static PRM_Template myTemplateList[]
int VISUALIZE() override
This determines if visualization will occur.
void CDNAME(UT_String &str, fpreal) override
void setFloat(int parmi, int vectori, fpreal t, fpreal value, PRM_AddKeyType add_key=PRM_AK_MARK_PENDING)
fpreal SYMMETRYDIST(fpreal) override
fpreal64 fpreal
Definition: SYS_Types.h:277
void setHitPrimitive(int primidx, fpreal) override
fpreal RAYHITW(fpreal) override
fpreal UPX(fpreal) override
fpreal DEPTH(fpreal t) override
fpreal RAYHITX(fpreal) override
int ACCUMSTENCIL() override
Whether accumulate stencil is currently on. We keep it off.
fpreal UPY(fpreal) override
fpreal ZEROWEIGHTCOLOR_R() override
fpreal SQUASH(fpreal) override
SOP_BrushEvent
Definition: SOP_BrushBase.h:31
fpreal RADIUSPRESSURE(fpreal) override
This is how much the HITPRESSURE should affect the RADIUS.
fpreal RAYORIENTZ(fpreal) override
int BITMAPCHAN(fpreal) override
Which channel of the bitmap brush should be used.
fpreal USERX(fpreal) override
SOP_BrushShape
Definition: SOP_BrushBase.h:65
GLboolean r
Definition: glcorearb.h:1222
constexpr SYS_FORCE_INLINE T & y() noexcept
Definition: UT_Vector3.h:654
GLfloat GLfloat GLfloat alpha
Definition: glcorearb.h:112
void BITMAP(UT_String &, fpreal) override
Name of the bitmap to use if bitmap brush is on, which it isn't.
fpreal SYMMETRYORIGX(fpreal) override
bool hasStrokeChanged(fpreal) override
int PRESERVENML() override
For Comb style brushes, this preserves the normal length.
fpreal SPLATTER(fpreal) override
Alpha noise in the brush space.
void setHitPressure(fpreal pressure, fpreal) override
SOP_BrushHairLen(OP_Network *net, const char *, OP_Operator *entry)
fpreal FGR(fpreal t) override
void ALPHANAME(UT_String &, fpreal) override
int MERGEMODE() override
Protected methods needed by SOP_BrushBase:
void setBrushOp(SOP_BrushOp op) override
void setHitPoint(int ptidx, fpreal) override
int altersGeometry() const override
constexpr SYS_FORCE_INLINE T & x() noexcept
Definition: UT_Vector3.h:652