Python drawLine one after the other.

Hey all,
So i’m delving into Python to do some visualization.

I’m using drawLine, something like rend.drawLine([ -5.0, 0, 2.85],[ 5.0, 0, alt], [1.0, 0.0, 0.0])
in while loop, but I need to draw one line after the other, so, adding a delay, I’m not a Python expert.
I have a logic brick set to pulse active, otherwise the lines only draw for one frame and disappear, I need them to draw one after the other but stay on the screen.

I’m sure this is a simple fix, can someone point out what I should do?

Thank so much. :slight_smile:

UPDATE:
I just noticed, and realized, using it with a logic brick set to pulse will run the script again and again, and the rasterizer will hit the roof… so how can I keep the drawLines on the screen, and draw them one iteration at a time? Thanks.

You’ll probably need to use a timer or somesort to drigger the next line with delay. Not sure if Delay sensor could be used here.
Problem with while loop is that it’ll run the whole while loop through before proceeding to the next frame.
So you wont be able to do this kind of line_draw, delay, line_draw, system with that.

But wouldn’t I want to run the whole while loop through, as each iteration of the loop draws another line? just that it happens so fast I can’t see it drawing line by line, and I can’t keep the lines on the screen without running the script repeatedly.
I tried pythons sleep command, but wasn’t working.

Thing is that for game engine to process stuff that actually are drawn on screen, iterations are not seen but rather you can only see the final result after the whole while loop is finished.

So this would work, and you would see each iterations:


v = 0

while v < 100000:
   v += 1
   print (v)


However with things that are manipulated and drawn on screen. Game engine only shows you what comes after a while loop (final result of it). For example:


    value = 0
    while value < 10:
        value += 0.001
        
        bge.render.drawLine([0,0,0], [0,value,0], [1,1,1])

This would only show the final result. Which is value 10.
Problem with time.sleep() is also that it’ll halt the whole game engine for the time put in sleep(). It would not be useful for “real-time delays”.

I attached a blend, on how I would use Delay for these kind of things.
delay_drawLine.blend (482 KB)

Thanks for the explanation and thanks a lot for the blend, im seeing if i can apply it to my visualisation at the moment…

That shouldn’t be the case. Instead i suspect you’ve not included the drawing code in the body of the while loop.

Sent from my Nexus 5 using Tapatalk

Hmm, drawLine() works inside while loop per iteration?
Because things like applyRotation etc don’t work in while loops as one rotation per iteration.

Anyhow it might be tricky to halt while loop for delay anyway?

countL = 0
countR = 0
altL = 2.85
altR = 2.85

while (countR < 50):
rend.drawLine([ -5.0, 0, 2.85],[ 5.0, 0, altR], [1.0, 0.0, 0.0])
countR = countR + 1
altR = altR - 0.12

this is my loop setup so far, i have included the draw code as far as I can tell…

Btw. when posting code use the code tags. You see what happens otherwise.
I suggest you chose some more descriptive variable names. That makes the code readable.

Your code will draw 50 lines at each execution of the Python controller.

As far as I understand you want to start with one line and end with 50 after a while.

So you need code that can draw a flexible number of lines. Your code nearly does that. But rather than hard-coding the number of lines, you can read it from a property.
hint.py


def readProperty():
   owner = bge.logic.getCurrentController().owner
   numberOfLines = owner["numberOfLines"]
   drawLines(numberOfLines)

You can add separate logic that sets the property to an according value. E.g. increasing the number of lines every 5 frames. You do not even need Python code to do that.

Thanks for the tip Monster,
I see what you mean, it’s just a bit hard to get my head around. So I’m drawing 50 lines with different trajectories sequentially, I should use a delay and an always sensor, and pass the while loop vector numbers to a property, and then increment it with the while loop?

That’s not what we’re advocating. You can draw as many times in one frame as you wish. If it is not working, it is the coordinates that you’re using, or the loop itself. Please post your code with CODE tags so that we can see the indentation.

Drawing
You need an always sensor to trigger the Python controller which draws the lines. This is needed as you need to draw the lines at each frame.

Increasing
You can use a delay sensor, always sensor, random sensor whatever sensor, that triggers the logic to increase the number of drawn lines. Just try it out. Hint: do no forget to set a limit. Drawing a lot of lines eats a lot of processing time.

Alternative:
You use objects with wire frame material. So you do not need to care the drawing as it will always been drawn as long as the object exists. Simply add one object after the other.


countL = 0
countR = 0
altL = 2.85
altR = 2.85




while (countR &lt; 50):
    
        rend.drawLine([ -5.0, 0, altL],[ 5.0, 0, altR], [1.0, 0.0, 0.0])
        countR = countR + 1
        countL = countL + 1
        altR = altR - 0.12

It’s working, but its visually appearing all at once, I need line by line.

I’ve been using blender since around the year 2000, but I rarely use the GE, so forgive my lack of knowledge when it comes to interacting Python with properties etc.

I have originally done this project with beziers, but rendering 2500 animated beziers at high quality just takes too long.

One way to approach it would be to have your line rendering happen in a separate script (or a separate section of the same script outside of the loop)- in your initial loop populate a list of all the lines you want to draw (call it SourceList or something), and make an empty list (call it DrawList or whatever), and then each frame append one entry from SourceList into DrawList. Your line-drawing script can then just loop through DrawList and draw every line in it. As DrawList grows each frame, new lines will appear while the old lines continue to exist.

You could also add a “life” entry into your DrawList entries that you add 1 to each frame, and remove the entry when it gets old enough- that way the old lines will gradually disappear. Not sure if that’s what you’re going for, but it’s an option. Having a “life” for each line also means you could do things like change the color of each line over the span of its life, if that interests you.

Thanks a lot for that recommendation, that’s an excellent idea and along the lines of what I was thinking of doing.
Actually I’m drawing 50 x 50 lines, for a total of 2500 lines, the end result is a diagram. I have a loop running within a loop which produces the end product beautifully, but I require to animate the creation of the lines. I could do it by creating 50 varied scripts connected to delays, but that isn’t really practical. Thanks for the idea.