!******************* curvetext_3d ************************** ! +++ ! Writes text along a curve. ! ! Text size will be modified if the curve is too short ! ! Function will fail if offset (text distance) curve ! to input curve not can be created (where text shall ! be written). ! ! --- !******************************************************** !sdesce Writes text along a curve GLOBAL GEOMETRY MODULE curvetext_3d( REF cur_id > "@t13 Select curve"; STRING intext*132:="My text" > "Text string"; FLOAT rels := 0.20 > "Parameter value for text start (0-1)"; STRING t_view*10:="xy" > "View xy, xz, yz"; STRING dir*3 :="pos" > "@ Direction along curve, pos/neg ,=pos)"; FLOAT t_size := 3.0 > "@ Text size"; FLOAT t_width := 50.0 > "@ Text width"; INT pen_col := 1 >"@ pen color"; FLOAT t_dist := 1.0 > "@ Distance of text to curve (offset)"); ! Internal variables: VECTOR p_in; ! Point corresponding to input rels FLOAT t_leng; ! Total length of input text string FLOAT tot_arcl; ! Total arc length of the input curve FLOAT rels_end; ! Relative arc length to end point FLOAT u_start; ! Start parameter value for trimming FLOAT u_end; ! End parameter value for trimming FLOAT rels_proj; ! Value rels for projected input curve FLOAT rels_trim; ! Value rels for trimmed curve REF cur_id_proj; ! Curve identity for projected curve REF cur_id_trim; ! Curve identity for trimmed curve REF cur_id_offset; ! Curve identity for offset curve REF cur_id_dir; ! Curve identity for text direction REF poi_id; ! Point identity for character position FLOAT a_leng; ! Available length for text FLOAT t_size_mod; ! Modified text size (mm) FLOAT t_width_mod; ! Modified width (% of text height) FLOAT t_leng_mod; ! Text length for t_width_mod FLOAT intextlangd; ! Text length before modification INT n_char; ! Number of characters of input string FLOAT delta; ! Relative arclength for one character INT i_char; ! Index character FLOAT alfa; ! Angle for text VECTOR vec_char; ! Character slope (in start point) VECTOR xaxis; ! X axis REF csy_id; ! BEGINMODULE ! +++ ! 1. Initializations and checks ! --- CSYS_1P(#20, "Basic_XYPlane", VEC(0,0,0),0,0,0:BLANK=1); CSYS_3P(#21, "Basic_XZPlane", VEC(0,0,0),VEC(1,0,0),VEC(0,0,1):BLANK=1); CSYS_3P(#22, "Basic_YZPlane", VEC(0,0,0),VEC(0,1,0),VEC(0,0,1):BLANK=1); csy_id := GLOBAL_REF(#20); IF t_view = "xz" OR t_view = "zx" OR t_view = "XZ" OR t_view = "ZX" THEN csy_id := GLOBAL_REF(#21); ENDIF; IF t_view = "yz" OR t_view = "zy" OR t_view = "YZ" OR t_view = "ZY" THEN csy_id := GLOBAL_REF(#22); ENDIF; MODE_LOCAL(csy_id); SET(TFONT=1,PEN=pen_col); ! Curve id IF cur_id = #0 THEN EXIT("curvetext_3d Program error (cur_id = #0)"); ENDIF; ! X axis xaxis := VEC(1.0,0.0); ! Check and set input text height and width IF t_size < 0.01 THEN EXIT("curvetext_3d Text height < 0.01"); ENDIF; SET(TSIZE=t_size); SET(TWIDTH=t_width); ! Check input relative arc length value IF rels < 0.0 OR rels > 1.0 THEN EXIT("curvetext_3d Relative value not between 0.0 and 1.0"); ENDIF; ! Initializations of internal variables rels_proj := -0.123456789; rels_trim := -0.12345678; cur_id_proj := #0; cur_id_trim := #0; cur_id_offset := #0; poi_id := #0; ! +++ ! 2. Create projected copy of input curve ! --- ! Total arc length for the input 3D curve tot_arcl:= ARCL(cur_id); ! Globalt start parameter value corresponding to rels u_start:= INV_ARCL(cur_id, rels*tot_arcl); ! Create projected curve (offset = 0.0) CUR_OFFS(#11,cur_id, 0.0 :BLANK=1); cur_id_proj := #11; ! Relative start value for the projected curve CUR_TRIM(#10,cur_id_proj,0.0, u_start:BLANK=1); rels_proj := ARCL(#10)/ARCL(cur_id_proj); ! +++ ! 3. Create trimmed part of curve ! --- ! The part curve is created in order to avoid offset problems ! in non-used parts of the input curve ! Length of input text with input text heigth and width t_leng:= TEXTL(intext); ! Increase the length for the offset curve (experience value 1.05) IF dir = "neg" THEN t_leng:= -1.05*t_leng; ELSE t_leng:= +1.05*t_leng; ENDIF; ! Total arclength of projected input curve tot_arcl:= ARCL(cur_id_proj); ! Relative parameter value for end of trimmed curve ! defined by the length of input string rels_end:=rels_proj+ t_leng/tot_arcl; ! Trim curve only if there is space enough for the text IF rels_end < 1 AND rels_end > 0 THEN ! Start and end parameter value for trim u_start:= INV_ARCL(cur_id_proj, rels_proj*tot_arcl); u_end:= INV_ARCL(cur_id_proj, rels_end*tot_arcl); IF dir = "pos" THEN CUR_TRIM(#12,cur_id_proj,u_start, u_end:BLANK=1); cur_id_trim := #12; ELSE CUR_TRIM(#13,cur_id_proj,u_end, u_start:BLANK=1); cur_id_trim := #13; ENDIF; rels_trim := 0.0; ELSE ! Do not create a trimmed curve cur_id_trim := cur_id_proj; rels_trim := rels_proj; ENDIF; ! +++ ! 3. Create offset curve for the text ! --- CUR_OFFS(#2,cur_id_trim,-t_dist :BLANK=1); cur_id_offset := #2; ! Reverse curve for text in negative direction IF dir = "neg" OR dir = "n" THEN CUR_TRIM(#1,#2, INV_ARCL(#2, ARCL(cur_id_offset)), 0.0:BLANK=1); cur_id_offset := #1; ENDIF; ! ! +++ ! 3. Text size modification and delta archlength for one character ! --- ! Available arc length a_leng:= (1.0-rels_trim)*ARCL(cur_id_offset); ! Check value IF a_leng < 0.001 THEN EXIT("curvetext_3d Wrong direction for text"); ENDIF; ! Calculate modified text size if curve length is too short ! (output values will be equal if space is enough) PART(#7,modtsize(intext, a_leng*0.97, t_size, t_width, t_size_mod, t_width_mod)); ! Set modified text height and width SET(TSIZE=t_size_mod); SET(TWIDTH=t_width_mod); ! Text length with modified text height t_leng_mod := TEXTL(intext); ! Number of characters in input string n_char := LENGTH(intext); ! Delta relative arc length for one character IF n_char > 0 THEN delta:= t_leng_mod/ ARCL(cur_id_offset)/n_char; ELSE EXIT("curvetext_3d Empty input string"); ENDIF; ! +++ ! 4. Create text along the curve ! --- ! Start loop character in input string FOR i_char := 1 TO n_char DO ! Position for the text POI_FREE(#3,ON(cur_id_offset, INV_ARCL(cur_id_offset, (rels_trim+(i_char-1)*delta)* ARCL(cur_id_offset)))); poi_id := #3; ! Slope for character vec_char := TANG(cur_id_offset, INV_ARCL(cur_id_offset, (rels_trim+(i_char-1)*delta)* ARCL(cur_id_offset))); vec_char := VECN(vec_char); ! Angle with (vec_char!xaxis)= !vec_char! * !xaxis! * COS(alfa) ! where !vec_char! = 1.0 and !xaxis! = 1.0 alfa := ARCCOS(vec_char * xaxis); ! Sign defined by the sign of the Y component of vec_char IF vec_char.y < 0.0 THEN alfa:= -alfa; ENDIF; ! Write current character TEXT(#6,ON(poi_id,0.0),alfa, SUBSTR(intext, i_char,1):TPMODE=1); ! Delete current point (otherwise must #3.1, #3.2, .. be handled) DEL(poi_id); ENDFOR; ! End loop i_char MODE_GLOBAL(); ENDMODULE